This can be easily done with a program transformation system.
The DMS Software Reengineering Toolkit is a general purpose program transformation system, and can be used with many languages (C++, COBOL, Java, EcmaScript, Fortran, ..) as well as specifically with C#.
DMS parses source code, builds Abstract Syntax Trees, and allows you to apply source-to-source patterns to transform your code from one C# program into another with whatever properties you wish. THe transformation rule to accomplish exactly the task you specified would be:
domain CSharp.
insert_trace():method->method
"[Trace]
\visibility \returntype \methodname(string \parametername)
{ \body } "
->
"\visibility \returntype \methodname(string \parametername)
{ Log.Trace(\CSharpString\(\methodname\),
\CSharpString\(\parametername\),
\parametername);
\body } "
The quote marks (") are not CSharp quote marks; rather, they are "domain quotes", and indicate that the content inside the quote marks is CSharp syntax (because we said, "domain CSharp"). The \foo notations are meta syntax.
This rule matches the AST representing the method you specified with the [Trace] annotation, and rewrites that AST into the traced form. The resulting AST is then prettyprinted back into source form, which you can compile. You probably need other rules to handle other combinations of arguments; in fact, you'd probably generalize the argument processing to produce (where practical) a string value for each scalar argument.
It should be clear you can do a lot more than just logging with this, and a lot more than just aspect-oriented programming, since you can express arbitrary transformations and not just before-after actions.