patterncsharpModerate
Detailed logs and keeping code clean (not AOP)
Viewed 0 times
keepinglogsdetailedcodeaopandnotclean
Problem
I have two quite mutually exclusive desires - detailed logs and keeping my code clean. It appears that you can only get either of these. By "logging" I mean logging and not tracing, so AOP adepts wouldn't appreciate it.
What I want to have is real description of action my program does, why it does these actions and so forth. For instance, 'failures' could either be real failures like 'fatal errors', or absolutely normal behavior depending on context: I don't like to check whether or not file exists before reading, I'll just try to open it and that could either fail or succeed. If it fails, I'll have an exception. But if reading this file is not really critical, the exception I get is not an error, it could be treated as just 'warning'.
When something really interesting happens, I want to see it directly without scrolling up and down my 500KB log file and trying to remember the code.
I've implemented a draft solution for this problem and I'd like to know what you think:
```
sealed class FileReader
{
private readonly string _fileName;
public FileReader(string fileName)
{
_fileName = fileName;
}
public string GetData(ExecutionContext context)
{
var fileExists = context.Execute(
string.Format("checking if {0} exists", _fileName),
ctx => File.Exists(_fileName));
if(!fileExists)
{
throw new FileNotFoundException();
}
var data = context.Execute(
string.Format("reading data from {0}", _fileName),
delegate { // can easily use lambdas and anonymous delegates
return File.ReadAllText(_fileName);
});
return data;
}
public override string ToString()
{
return string.Format("FileReader(file={0})", _fileName);
}
}
...
sealed class FileProcessor
{
private readonly FileReader _fileReader;
private readonly DataProcessor _dataProcessor;
public FileProcessor(FileReader fileRea
What I want to have is real description of action my program does, why it does these actions and so forth. For instance, 'failures' could either be real failures like 'fatal errors', or absolutely normal behavior depending on context: I don't like to check whether or not file exists before reading, I'll just try to open it and that could either fail or succeed. If it fails, I'll have an exception. But if reading this file is not really critical, the exception I get is not an error, it could be treated as just 'warning'.
When something really interesting happens, I want to see it directly without scrolling up and down my 500KB log file and trying to remember the code.
I've implemented a draft solution for this problem and I'd like to know what you think:
```
sealed class FileReader
{
private readonly string _fileName;
public FileReader(string fileName)
{
_fileName = fileName;
}
public string GetData(ExecutionContext context)
{
var fileExists = context.Execute(
string.Format("checking if {0} exists", _fileName),
ctx => File.Exists(_fileName));
if(!fileExists)
{
throw new FileNotFoundException();
}
var data = context.Execute(
string.Format("reading data from {0}", _fileName),
delegate { // can easily use lambdas and anonymous delegates
return File.ReadAllText(_fileName);
});
return data;
}
public override string ToString()
{
return string.Format("FileReader(file={0})", _fileName);
}
}
...
sealed class FileProcessor
{
private readonly FileReader _fileReader;
private readonly DataProcessor _dataProcessor;
public FileProcessor(FileReader fileRea
Solution
For what it's worth after all this time you asked the question:
Is it worth it?
The answer is: No.
You said one requirement is to keep your code clean. You have fully achieved the total opposite of this. Lets take
A reasonably experienced developer can read this code and understand what it is doing in about 5sec.
You have turned this four-liner into a mess of disjoint statements which take about 10 times longer to read through and understand what the code is doing.
You also run into the same problem as you do with commenting every statement: You write the code twice. Once for the compiler to execute and once for the developer/log file to read/record. Admittedly with detailed logging you can run into similar issues.
You also said you don't want tracing while in fact at least your example code boils down to exactly that. So using an AOP framework might be the better alternative in your case.
Is it worth it?
The answer is: No.
You said one requirement is to keep your code clean. You have fully achieved the total opposite of this. Lets take
GetData() as an example. Without the ExecutionContext code the method would read this:public string GetData(ExecutionContext context)
{
if(!File.Exists(_fileName))
{
throw new FileNotFoundException();
}
return File.ReadAllText(_fileName);
}A reasonably experienced developer can read this code and understand what it is doing in about 5sec.
You have turned this four-liner into a mess of disjoint statements which take about 10 times longer to read through and understand what the code is doing.
You also run into the same problem as you do with commenting every statement: You write the code twice. Once for the compiler to execute and once for the developer/log file to read/record. Admittedly with detailed logging you can run into similar issues.
You also said you don't want tracing while in fact at least your example code boils down to exactly that. So using an AOP framework might be the better alternative in your case.
Code Snippets
public string GetData(ExecutionContext context)
{
if(!File.Exists(_fileName))
{
throw new FileNotFoundException();
}
return File.ReadAllText(_fileName);
}Context
StackExchange Code Review Q#3544, answer score: 12
Revisions (0)
No revisions yet.