I'm trying to figure out how to support the following example scenario
ill be using C# as the example language.
Scenario
NASA is sending Rovers and Satellites to different Planets
these vehicles need a lot of logging, and to reduce clutter, would like to be able to filter these logs in the following ways:
i should be able to combine/pick one of these:
- Log only Rovers in Mercury
- Log everything on Mars
- Log all Satellites
Implementation
Object Graph
so we have 3 object types, Planet, Rover and Satellite
Earth contains 3 Satellite's
Mars contains 1 Satellite, and 2 Rovers.
Mercury contains 2 Satellite's and 1 Rover.
the usual way to add a log to objects is as such:
public class Mars : Planet {
private static ILog Log = LogManager.GetCurrentClassLogger();
}
this would usually return a logger named "NASA.Mars" which makes it easy to simply configure the framework to log all "NASA.Mars" the same would happen with a Rover
public class Rover {
private static ILog Log = LogManager.GetCurrentClassLogger();
}
I would get a logger named "NASA.Rover"
but how could would I know that rover is in mercury? since this is a requirement of the logging subsystem, it shouldn't exist as property on the Rover class.
Idea
Dependency injection
if i design my classes to accept an ILog instance in the constructor I could in theory, control a child objects log name
(possible to use the parent Planet class, omitted for brevity)
public class Mars : Planet {
private static ILog Log = LogManager.GetCurrentClassLogger();
void Mars() {
this.Rovers.Add(new Rover(LogManager.GetLogger(Log.Name + ".Rover"));
}
}
public class Rover {
private ILog Log;
void Rover(ILog log) {
Log = log;
}
}
My problems with this approach:
- creating a logger for each child object feels kind of "off" perhaps even an anti-pattern
- this can get very messy when dealing with deeper levels of hierarchy (think planet -> area -> station -> rover )
- deciphering object hierarchy from the logger name string (NASA.Mars.Rover) is problematic (wild cards sometimes wont be enough, some names might not be unique enough).
I'm looking for a good idea to solve this, without cluttering code, something generic
Planet
actually contains any behaviour ? Why subclassing withMars
,Mercury
, ... ? Can these classes be replaced with an enum ?