Ok so Ive run into a situation I would like to resolve with minimum impact on our development group.
We are using log4net as our logging framework in a largish c# system (~40 production assemblies).
Now our support end wants to be able to correlate logged events with a database they maintain separately. A reasonable request.
In production our main log repository is the Windows Event-Log.
At the developer side our current pattern is this:
Whenever you want to log from a component, you instantiate a logger like this at the top of the class:
private static readonly ILogger Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod())
If you need stuff in the logging context, you put it in as-early-as-possible in the flow of every Thread, ie. at the receiving end of service calls etc.
Whenever you want to do logging, you simply do
Log.Warn(str, ex) - (or Info, Error etc)
Now we want to "fix" this log-entry to a unique "eventId", and we can supply an extension method to ILogger, that will allow us to do:
Log.Warn(int, str, ex), when "int" is a number with these properties:
It is "mapped" to a durable store.
It points to one and only one Log
entry
If the source code Log statement is removed, the Id is not
reused for a new log statement.
My immediate solution would be to maintain a global enum, that would cover the set of possible "eventId"'s and just instruct the developers to "use them only once".
We would then proceed to do some sort of "intelligent" mapping between our Namespaces and "CategoryId" - f.ex eveything in the "BusinessLayer" namespace gets one categoryId assigned.
But I think there is something I'm missing....
Any thoughts would be appreciated on:
How do you use EventId and CategoryId in your large systems? (Or "What" do you use them for)
Does any of you have an example of a "dynamic" way of creating the EventId's, in such a way that you can maintain the simple approach to logging, that does not require the developer to supply a unique Id at code-statement level.
Sorry if my question is too broad, I am aware that Im fishing a bit here.
Related
Background: I need parts of my system to be able to push various status messages to some data structure so that they can be consumed by a caller, without passing the data structure into methods explicitly, and where the needs of the callers can differ.
Detail: my application has two (and conceivably more) heads, an ASP.NET MVC 5 web site and a Windows service. So normally, while the composition root of a web application would be the web site itself, I am using a separate composition root that both these "front ends" connect to--this allows them to share a common configuration, as almost all of their dependency injection will be 100% identical. Plus, for testing, I've decided to keep most of the code out of the web site as truly unit testing controllers is problematic.
So my code needs to be able to run outside of the context of any web request. Similarly, anything the service does on a schedule needs to be able to be run as an on-demand job from the web site. So most of the heavy-lifting code in my application is NOT in the web site or the service.
Now, back to the needs of my status messages:
Some status messages will be logged, but potentially more will be logged when run as a service. It's okay to queue the log items and save them at the end.
When, say, a job is run on-demand from the web site, fewer things may be logged because any issues the user can take care of will be displayed directly to the user, and for debug purposes we only care about outright errors happening. New messages need to be pushed to the web site immediately (probably through websockets).
Also, a job may be run in debug or verbose mode, so that more informational or warning messages are produced one time (say on the web) than would be the case another time (from the headless service). Code generating messages shouldn't worry about these details at all, unless something that would hurt performance in production is placed inside compiler directives for debug mode).
Additionally, some of the code pushes errors, warnings, or information into the objects that are returned from a request. These are easy to handle. But other errors, warnings, or information (such as errors that prevent said requested objects from being fetched at all) need to bubble up outside of the normal return values.
Right now I'm using something that seems less than ideal: all my methods have to accept a parameter that they can modify in order to bubble up such errors. For example:
public IReadOnlyCollection<UsableItem> GetUsableItems(
ReadOnlyHashSet<string> itemIds,
List<StatusMessage> statusMessages
) {
var resultItems = _itemService.Get(itemIds);
var resultItemsByHasFrobDuplicate = resultItems
.GroupBy(i => i.FrobId)
.ToLookup(grp => grp.Count() > 1, grp => grp.ToList());
statusMessages
.AddRange(
resultItemsByHasFrobDuplicate[true]
.Select(items => $#"{items[0].FrobId
} is used by multiple items {string.Join(",", items.Select(i => i.usableItemId))
}")
);
return resultItemsByHasFrobDuplicate[false]
.Select(grp => grp.First())
.ToList()
.AsReadOnly();
}
So you can see here that while normally items can be in the return value from the method (and these items can even have their own status messages placed on them), others cannot—the calling code can't deal with duplicates and expects a collection of UsableItem objects that do NOT have duplicate FrobId values. The situation of the duplicates is unexpected and needs to bubble up to the user or the log.
The code would be greatly improved by being able to remove the statusMessages parameter and do something more like CurrentScope.PushMessage(message) and know that these messages will be properly handled based on their severity or other rules (the real messages are an object with several properties).
Oh, and I left something out in the code above. What I really have to do is:
_itemService.Get(itemIds, statusMessages); // -- take the darn parameter everywhere
Argh. That is not ideal.
I instantly thought of MiniProfiler.Current as similar, where it's available anywhere but it's scoped to the current request. But I don't understand how it is able to be static, yet segregate any Step calls between different requests so that a user doesn't get another user's steps in his output. Plus, doesn't it only work for MVC? I need this to work when there is no MVC, just non-web code.
Can anyone suggest a way to improve my code and not have to pass around a list to method after method? Something that will work with unit tests is also important, as I need to be able to set up a means to capture the bubbled errors in my mock within a unit test (or be able to do nothing at all if that's not the desired portion of the system to test).
P.S. I don't mind tactful criticism of my little ToLookup pattern above for separating duplicates. I use that technique a lot and would be interested in a better way.
I think you're just looking at this the wrong way. None of this actually involves or really is related to a request. You simply need some service you can inject which pushes messages out. How it does that is inconsequential, and the whole point of dependency injection is that the class with the dependency shouldn't know or care.
Create an interface for your messaging service:
public interface IMessagingService
{
void PushMessage(string message);
}
Then, you should alter your class which contains GetUsableItems a bit to inject the messaging service into the constructor. In general, method injection (what you're doing currently by passing List<StatusMessages> into the method) is frowned upon.
public class MyAwesomeClass
{
protected readonly IMessagingService messenger;
public MyAwesomeClass(IMessagingService messenger)
{
this.messenger = messenger;
}
Then, in your method:
messenger.PushMessage("My awesome message");
The implementation of this interface, then will probably vary based on whether it's injected in the web app or the windows service. Your web app will likely have an implementation that simply utilizes its own code to push messages, whereas the windows service will likely need an implementation that utilizes HttpClient to make requests to your web app. Setup your DI container to inject the right implementation for the right application and you're done.
I'm not a hater of singletons, but I know they get abused and for that reason I want to learn to avoid using them when not needed.
I'm developing an application to be cross platform (Windows XP/Vista/7, Windows Mobile 6.x, Windows CE5, Windows CE6). As part of the process I am re-factoring out code into separate projects, to reduce code duplication, and hence a chance to fix the mistakes of the inital system.
One such part of the application that is being made separate is quite simple, its a profile manager. This project is responsible for storing Profiles. It has a Profile class that contains some configuration data that is used by all parts of the application. It has a ProfileManager class which contains Profiles. The ProfileManager will read/save Profiles as separate XML files on the harddrive, and allow the application to retrieve and set the "active" Profile. Simple.
On the first internal build, the GUI was the anti-pattern SmartGUI. It was a WinForms implementation without MVC/MVP done because we wanted it working sooner rather than being well engineered. This lead to ProfileManager being a singleton. This was so from anywhere in the application, the GUI could access the active Profile.
This meant I could just go ProfileManager.Instance.ActiveProfile to retrieve the configuration for different parts of the system as needed. Each GUI could also make changes to the profile, so each GUI had a save button, so they all had access to ProfileManager.Instance.SaveActiveProfile() method as well.
I see nothing wrong in using the singleton here, and because I see nothing wrong in it yet know singletons aren't ideal. Is there a better way this should be handled? Should an instance of ProfileManager be passed into every Controller/Presenter? When the ProfileManager is created, should other core components be made and register to events when profiles are changed. The example is quite simple, and probably a common feature in many systems so think this is a great place to learn how to avoid singletons.
P.s. I'm having to build the application against Compact Framework 3.5, which does limit alot of the normal .Net Framework classes which can be used.
One of the reasons singletons are maligned is that they often act as a container for global, shared, and sometimes mutable, state. Singletons are a great abstraction when your application really does need access to global, shared state: your mobile app that needs to access the microphone or audio playback needs to coordinate this, as there's only one set of speakers, for instance.
In the case of your application, you have a single, "active" profile, that different parts of the application need to be able to modify. I think you need to decide whether or not the user's profile truly fits into this abstraction. Given that the manifestation of a profile is a single XML file on disk, I think it's fine to have as a singleton.
I do think you should either use dependency injection or a factory pattern to get a hold of a profile manager, though. You only need to write a unit test for a class that requires the use of a profile to understand the need for this; you want to be able to pass in a programatically created profile at runtime, otherwise your code will have a tightly coupled dependency to some XML file on disk somewhere.
One thing to consider is to have an interface for your ProfileManager, and pass an instance of that to the constructor of each view (or anything) that uses it. This way, you can easily have a singleton, or an instance per thread / user / etc, or have an implementation that goes to a database / web service / etc.
Another option would be to have all the things that use the ProfileManager call a factory instead of accessing it directly. Then that factory could return an instance, again it could be a singleton or not (go to database or file or web service, etc, etc) and most of your code doesn't need to know.
Doesn't answer your direct question, but it does make the impact of a change in the future close to zero.
"Singletons" are really only bad if they're essentially used to replace "global" variables. In this case, and if that's what it's being used for, it's not necessarily Singleton anyway.
In the case you describe, it's fine, and in fact ideal so that your application can be sure that the Profile Manager is available to everyone that needs it, and that no other part of the application can instantiate an extra one that will conflict with the existing one. This reduces ugly extra parameters/fields everywhere too, where you're attempting to pass around the one instance, and then maintaining extra unnecessary references to it. As long as it's forced into one and only one instantiation, I see nothing wrong with it.
Singleton was designed to avoid multiple instantiations and single point of "entry". If that's what you want, then that's the way to go. Just make sure it's well documented.
We have a server written in C# (Framework 3.5 SP1). Customers write client applications using our server API. Recently, we created several levels of license schemes like Basic, Intermediate and All. If you have Basic license then you can call few methods on our API. Similarly if you have Intermediate you get some extra methods to call and if you have All then you can call all the methods.
When server starts it gets the license type. Now in each method I have to check the type of license and decide whether to proceed further with the function or return.
For example, a method InterMediateMethod() can only be used by Intermediate License and All license. So I have to something like this.
public void InterMediateMethod()
{
if(licenseType == "Basic")
{
throw new Exception("Access denied");
}
}
It looks like to me that it is very lame approach. Is there any better way to do this? Is there any declarative way to do this by defining some custom attributes? I looked at creating a custom CodeAccessSecurityAttribute but did not get a good success.
Since you are adding the "if" logic in every method (and god knows what else), you might find it easier to use PostSharp (AOP framework) to achieve the same, but personally, I don't like either of the approaches...
I think it would be much cleaner if you'd maintained three different branches (source code) for each license, which may add a little bit of overhead in terms of maintenance (maybe not), but at least keep it clean and simple.
I'm also interested what others have to say about it.
Good post, I like it...
Possibly one easy and clean approach would be to add a proxy API that duplicates all your API methods and exposes them to the client. When called, the proxy would either forward the call to your real method, or return a "not licensed" error. The proxies could be built into three separate (basic, intermediate, all) classes, and your server would create instances of the approprate proxy for your client's licence. This has the advantage of having minimal performance overhead (because you only check the licence once). You may not even need to use a proxy for the "all" level, so it'll get maximum performance. It may be hard to slip this in depending on your existing design though.
Another possibility may be to redesign and break up your APIs into basic/intermediate/all "sections", and put them in separate assemblies, so the entire assembly can be enabled/disabled by the licence, and attempting to call an unlicensed method can just return a "method not found" error (e.g. a TypeLoadException will occur automatically if you simply haven't loaded the needed assembly). This will make it much easier to test and maintain, and again avoids checking at the per-method level.
If you can't do this, at least try to use a more centralised system than an "if" statement hand-written into every method.
Examples (which may or may not be compatible with your existing design) would include:
Add a custom attribute to each method and have the server dispatch code check this attribute using reflection before it passes the call into the method.
Add a custom attribute to mark the method, and use PostSharp to inject a standard bit of code into the method that will read and test the attribute against the licence.
Use PostSharp to add code to test the licence, but put the licence details for each method in a more data driven system (e.g. use an XML file rather than attributes to describe the method permissions). This will allow you to easily change the licensing across the entire server by editing a single file, and allow you to easily add whole new levels or types of licences in future.
Hope that gives you some ideas.
You might really want to consider buying a licensing solution rather than rolling your own. We use Desaware and are pretty happy with it.
Doing licensing at the method level is going to take you into a world of hurt. Maintenance on that would be a nightmare, and it won't scale at all.
You should really look at componentizing your product. Your code should roughly fall into "features", which can be bundled into "components". The trick is to make each component do a license check, and have a licensing solution that knows if a license includes a component.
Components for our products are generally on the assembly level, but for our web products they can get down to the ASP.Net server control level.
I wonder how the people are licensing the SOA services. They can be licensed per service or per end point.
That can be very hard to maintain.
You can try with using strategy pattern.
This can be your starting point.
I agree with the answer from #Ostati that you should keep 3 branches of your code.
What I would further expand on that is then I would expose 3 different services (preferably WCF services) and issue certificates that grant access to the specific service. That way if anyone tried to access the higher level functionality they would just not be able to access the service period.
I'm fairly new to log4net, and I can't seem to find any clear examples of how to handle this situation.
I have a communication stack that consists of three layers: hardware, transport, and protocol. The three layers are contained inside of a manager class. As far as the user of the code is concerned they create the manager with a hardware type (Serial,Ethernet,SSL,etc) and provide an address. There can be multiple manager instances, each connecting to a different target.
I'd like my output to give context of which connection the particular message came from (127.0.0.1 or COM5 etc). The ThreadContext isn't much use because the manager can be called from any thread and each layer runs on its own thread.
Is there any way to set a context based on a particular instance of an object? Or is there a better way to handle the output formatting?
A way of adding additional per-message context is to not only log a string message but create your own message object containing both log information and the connection hardware type (and any additional information you would like to include).
You can find an example of this here.
Another option could be using a Nested Diagnostics Context:
using(NDC.Push("<Connection type>"))
{
// perform your logging here
}
The NDC data will be included with the message and can be output with the %ndc pattern. A note of warning though, the NDC will be included with ANY messages logged within its using scope, which is perhaps why you would consider going the custom message route.
You should use an overload of LogManager.GetLogger() that takes string name, this way you can pass pretty much anything as the logger name.
First off, I wish context based storage was consistent across the framework!
With that said, I'm looking for an elegant solution to make these properties safe across ASP.NET, WCF and any other multithreaded .NET code. The properties are located in some low-level tracing helpers (these are exposed via methods if you're wondering why they're internal).
I'd rather not have a dependency on unneeded assemblies (like System.Web, etc). I don't want to require anyone using this code to configure anything. I just want it to work ;) That may be too tall of an order though...
Anyone have any tricks up their sleeves? (I've seen Spring's implementation)
internal static string CurrentInstance
{
get
{
return CallContext.LogicalGetData(currentInstanceSlotName) as string;
}
set
{
CallContext.LogicalSetData(currentInstanceSlotName, value);
}
}
internal static Stack<ActivityState> AmbientActivityId
{
get
{
Stack<ActivityState> stack = CallContext.LogicalGetData(ambientActivityStateSlotName) as Stack<ActivityState>;
if (stack == null)
{
stack = new Stack<ActivityState>();
CallContext.LogicalSetData(ambientActivityStateSlotName, stack);
}
return stack;
}
}
Update
By safe I do not mean synchronized. Background on the issue here
Here is a link to (at least part of) NHibernate's "context" implementation:
https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Context/
It is not clear to me exactly where or how this comes into play in the context of NHibernate. That is, if I wanted to store some values in "the context" would I get "the context" from NHibernate and add my values? I don't use NHibernate, so I don't really know.
I suppose that you could look and determine for yourself if this kind of implementation would be useful to you. Apparently the idea would be to inject the desired implementation, depending on the type of application (ASP.NET, WCF, etc). That probably implies some configuration (maybe minimal if one were to use MEF to load "the" ICurrentSessionContext interface).
At any rate, I found this idea interesting when I found it some time ago while searching for information on CallContext.SetData/GetData/LogicalSetData/LogicalGetData, Thread.SetData/GetData, [ThreadStatic], etc.
Also, based on your use of CallContext.LogicalSetData rather than CallContext.SetData, I assume that you want to take advantage of the fact that information associated with the logical thread will be propagated to child threads as opposed to just wanting a "thread safe" place to store info. So, if you were to set (pr Push) the AmbientActivity in your app's startup and then not push any more activities, any subsequent threads would also be part of that same activity since data stored via LogicalSetData is inherited by child threads.
If you have learned anything in the meantime since you first asked this question I would be very interested in hearing about it. Even if you haven't, I would be interested in learning about what you are doing with the context.
At the moment, I am working on maintaining some context information for logging/tracing (similar to Trace.CorrelationManager.ActivityId and Trace.CorrelationManager.LogicalOpertionStack and log4net/NLog context support). I would like to save some context (current app, current app instance, current activity (maybe nested)) for use in an app or WCF service AND I want to propagate it "automatically" across WCF service boundaries. This is to allow logging statements logged in a central repository to be correlated by client/activity/etc. We would be able to query and correlate for all logging statements by a specific instance of a specific application. The logging statements could have been generated on the client or in one or more WCF services.
The WCF propagation of ActivityId is not necessarily sufficient for us because we want to propagate (or we think we do) more than just the ActivityId. Also, we want to propagate this information from Silverlight clients to WCF services and Trace.CorrelationManager is not available in Silverlight (at least not in 4.0, maybe something like it will be available in the future).
Currently I am prototyping the propagation of our "context" information using IClientMessageInspector and IDispatchMessageInspector. It looks like it will probably work ok for us.
Regarding a dependency on System.Web, the NHibernate implementation does have a "ReflectiveHttpContext" that uses reflection to access the HttpContext so there would not be a project dependency on System.Web. Obviously, System.Web would have to be available where the app is deployed if HttpContext is configured to be used.
I don't know that using CallContext is the right move here if the desire is simply to provide thread-safe access to your properties. If that is the case, the lock statement is all you need.
However, you have to make sure you are applying it correctly.
With CallContext, you are going to get thread-safe access because you are going to have separate instances of CallContext when calls come in on different threads (or different stores, rather). However, that's very different from making access to a resource thread-safe.
If you want to share the same value across multiple threads, then the lock statement is the way to go. Otherwise, if you want specific values on a per-thread/call basis, use the CallContext, or use the static GetData/SetData methods on the Thread class, or the ThreadStatic attribute (or any number of thread-based storage mechanisms).