I use the TraceSource class for logging in my .NET projects.
However a point that has never been clear to me is, what the intent of the id parameter in the TraceEvent method. Currently, I always set it to 0.
But what is the expected or typical useful usage of it?
I can think of a few possibilities:
It is an ID for the occurrence of the event (i.e. the same line of code produces a different ID on each execution);
It is an ID for the method call (i.e. you can infer the line of code from the ID);
It is an ID for a family of similar events (e.g. all error messages that say that the database is absent share the same ID);
It is an ID for a set of events that are related to a logical operation, in combination with the TraceEventType.(Start|Stop|Suspend|Resume|Transfer) enumeration values;
I've asked myself the same question and I didn't found anything to clarify this in any Microsoft documentation.
What I've manage to find is an article written by a Microsoft MVP, Richard Grimes:
"The id parameter is whatever you choose it to be, there is no compulsion that a particular ID is associated with a particular format message."
He uses 0, for the id argument, in all examples.
In MSDN articles, I've seen it used random, not providing any additional info.
I believe that you can use in any way that helps you best when reading the logs, as long as you maintain the same code convention. It may prove useful afterwards in trace filtering, if you want to use the SourceFilter.ShouldTrace method, that accept an id argument too.
I use it to describe the error type, if I have an error, or use 0 for anything else.
As far as I've seen in the documentation, it's not specifically intended for one purpose. I think it's there for you to tie in with your own logic for tracing events. The ShouldTrace() method on SourceFilter takes a matching id parameter, so you can also use it to determine which events or event types go where.
Personally, when I use TraceSource (which admittedly isn't much, having only discovered it recently) I use it to track event types or categories. In one application I already had an enum for event types that I was using with another logging method, with values Debug, Info, Warn, Error, Fatal, so I cast that to int and used that as the id, which helped with filtering later so I could filter out anything below the level I was interested in to de-clutter the trace.
Another possibility is that you could use different values to relate to different parts of the application, so Data Access = 1, User Accounts = 2, Product Logic = 3, Notifications = 4, UI = 5 etc. Again, you could then use this to filter the trace down to only the type of thing you're looking at.
Alternatively, you could (as you suggested) use different id values to mean different event types, so you could use them like error codes so that (for example) any time you saw an id of 26 you'd know that the database connection could not be established, or whatever.
It doesn't particularly matter what you use the id parameter for, as long as:
It is useful to you in building and debugging the program
It is clear and understandable to programmers reading through your code
It is used consistently throughout the program
One possibility is that you could have a centralised class that manages the event ids and provides the values based on some sort of input to make sure that the whole application uses the same id for the same thing.
Related
I'm writing a library that has several public classes and methods, as well as several private or internal classes and methods that the library itself uses.
In the public methods I have a null check and a throw like this:
public int DoSomething(int number)
{
if (number == null)
{
throw new ArgumentNullException(nameof(number));
}
}
But then this got me thinking, to what level should I be adding parameter null checks to methods? Do I also start adding them to private methods? Should I only do it for public methods?
Ultimately, there isn't a uniform consensus on this. So instead of giving a yes or no answer, I'll try to list the considerations for making this decision:
Null checks bloat your code. If your procedures are concise, the null guards at the beginning of them may form a significant part of the overall size of the procedure, without expressing the purpose or behaviour of that procedure.
Null checks expressively state a precondition. If a method is going to fail when one of the values is null, having a null check at the top is a good way to demonstrate this to a casual reader without them having to hunt for where it's dereferenced. To improve this, people often use helper methods with names like Guard.AgainstNull, instead of having to write the check each time.
Checks in private methods are untestable. By introducing a branch in your code which you have no way of fully traversing, you make it impossible to fully test that method. This conflicts with the point of view that tests document the behaviour of a class, and that that class's code exists to provide that behaviour.
The severity of letting a null through depends on the situation. Often, if a null does get into the method, it'll be dereferenced a few lines later and you'll get a NullReferenceException. This really isn't much less clear than throwing an ArgumentNullException. On the other hand, if that reference is passed around quite a bit before being dereferenced, or if throwing an NRE will leave things in a messy state, then throwing early is much more important.
Some libraries, like .NET's Code Contracts, allow a degree of static analysis, which can add an extra benefit to your checks.
If you're working on a project with others, there may be existing team or project standards covering this.
If you're not a library developer, don't be defensive in your code
Write unit tests instead
In fact, even if you're developing a library, throwing is most of the time: BAD
1. Testing null on int must never be done in c# :
It raises a warning CS4072, because it's always false.
2. Throwing an Exception means it's exceptional: abnormal and rare.
It should never raise in production code. Especially because exception stack trace traversal can be a cpu intensive task. And you'll never be sure where the exception will be caught, if it's caught and logged or just simply silently ignored (after killing one of your background thread) because you don't control the user code. There is no "checked exception" in c# (like in java) which means you never know - if it's not well documented - what exceptions a given method could raise. By the way, that kind of documentation must be kept in sync with the code which is not always easy to do (increase maintenance costs).
3. Exceptions increases maintenance costs.
As exceptions are thrown at runtime and under certain conditions, they could be detected really late in the development process. As you may already know, the later an error is detected in the development process, the more expensive the fix will be. I've even seen exception raising code made its way to production code and not raise for a week, only for raising every day hereafter (killing the production. oops!).
4. Throwing on invalid input means you don't control input.
It's the case for public methods of libraries. However if you can check it at compile time with another type (for example a non nullable type like int) then it's the way to go. And of course, as they are public, it's their responsibility to check for input.
Imagine the user who uses what he thinks as valid data and then by a side effect, a method deep in the stack trace trows a ArgumentNullException.
What will be his reaction?
How can he cope with that?
Will it be easy for you to provide an explanation message ?
5. Private and internal methods should never ever throw exceptions related to their input.
You may throw exceptions in your code because an external component (maybe Database, a file or else) is misbehaving and you can't guarantee that your library will continue to run correctly in its current state.
Making a method public doesn't mean that it should (only that it can) be called from outside of your library (Look at Public versus Published from Martin Fowler). Use IOC, interfaces, factories and publish only what's needed by the user, while making the whole library classes available for unit testing. (Or you can use the InternalsVisibleTo mechanism).
6. Throwing exceptions without any explanation message is making fun of the user
No need to remind what feelings one can have when a tool is broken, without having any clue on how to fix it. Yes, I know. You comes to SO and ask a question...
7. Invalid input means it breaks your code
If your code can produce a valid output with the value then it's not invalid and your code should manage it. Add a unit test to test this value.
8. Think in user terms:
Do you like when a library you use throws exceptions for smashing your face ? Like: "Hey, it's invalid, you should have known that!"
Even if from your point of view - with your knowledge of the library internals, the input is invalid, how you can explain it to the user (be kind and polite):
Clear documentation (in Xml doc and an architecture summary may help).
Publish the xml doc with the library.
Clear error explanation in the exception if any.
Give the choice :
Look at Dictionary class, what do you prefer? what call do you think is the fastest ? What call can raises exception ?
Dictionary<string, string> dictionary = new Dictionary<string, string>();
string res;
dictionary.TryGetValue("key", out res);
or
var other = dictionary["key"];
9. Why not using Code Contracts ?
It's an elegant way to avoid the ugly if then throw and isolate the contract from the implementation, permitting to reuse the contract for different implementations at the same time. You can even publish the contract to your library user to further explain him how to use the library.
As a conclusion, even if you can easily use throw, even if you can experience exceptions raising when you use .Net Framework, that doesn't mean it could be used without caution.
Here are my opinions:
General Cases
Generally speaking, it is better to check for any invalid inputs before you process them in a method for robustness reason - be it private, protected, internal, protected internal, or public methods. Although there are some performance costs paid for this approach, in most cases, this is worth doing rather than paying more time to debug and to patch the codes later.
Strictly Speaking, however...
Strictly speaking, however, it is not always needed to do so. Some methods, usually private ones, can be left without any input checking provided that you have full guarantee that there isn't single call for the method with invalid inputs. This may give you some performance benefit, especially if the method is called frequently to do some basic computation/action. For such cases, doing checking for input validity may impair the performance significantly.
Public Methods
Now the public method is trickier. This is because, more strictly speaking, although the access modifier alone can tell who can use the methods, it cannot tell who will use the methods. More over, it also cannot tell how the methods are going to be used (that is, whether the methods are going to be called with invalid inputs in the given scopes or not).
The Ultimate Determining Factor
Although access modifiers for methods in the code can hint on how to use the methods, ultimately, it is humans who will use the methods, and it is up to the humans how they are going to use them and with what inputs. Thus, in some rare cases, it is possible to have a public method which is only called in some private scope and in that private scope, the inputs for the public methods are guaranteed to be valid before the public method is called.
In such cases then, even the access modifier is public, there isn't any real need to check for invalid inputs, except for robust design reason. And why is this so? Because there are humans who know completely when and how the methods shall be called!
Here we can see, there is no guarantee either that public method always require checking for invalid inputs. And if this is true for public methods, it must also be true for protected, internal, protected internal, and private methods as well.
Conclusions
So, in conclusion, we can say a couple of things to help us making decisions:
Generally, it is better to have checks for any invalid inputs for robust design reason, provided that performance is not at stake. This is true for any type of access modifiers.
The invalid inputs check could be skipped if performance gain could be significantly improved by doing so, provided that it can also be guaranteed that the scope where the methods are called are always giving the methods valid inputs.
private method is usually where we skip such checking, but there is no guarantee that we cannot do that for public method as well
Humans are the ones who ultimately use the methods. Regardless of how the access modifiers can hint the use of the methods, how the methods are actually used and called depend on the coders. Thus, we can only say about general/good practice, without restricting it to be the only way of doing it.
The public interface of your library deserves tight checking of preconditions, because you should expect the users of your library to make mistakes and violate the preconditions by accident. Help them understand what is going on in your library.
The private methods in your library do not require such runtime checking because you call them yourself. You are in full control of what you are passing. If you want to add checks because you are afraid to mess up, then use asserts. They will catch your own mistakes, but do not impede performance during runtime.
Though you tagged language-agnostic, it seems to me that it probably doesn't exist a general response.
Notably, in your example you hinted the argument: so with a language accepting hinting it'll fire an error as soon as entering the function, before you can take any action.
In such a case, the only solution is to have checked the argument before calling your function... but since you're writing a library, that cannot have sense!
In the other hand, with no hinting, it remains realistic to check inside the function.
So at this step of the reflexion, I'd already suggest to give up hinting.
Now let's go back to your precise question: to what level should it be checked?
For a given data piece it'd happen only at the highest level where it can "enter" (may be several occurrences for the same data), so logically it'd concern only public methods.
That's for the theory. But maybe you plan a huge, complex, library so it might be not easy to ensure having certainty about registering all "entry points".
In this case, I'd suggest the opposite: consider to merely apply your controls everywhere, then only omit it where you clearly see it's duplicate.
Hope this helps.
In my opinion you should ALWAYS check for "invalid" data - independent whether it is a private or public method.
Looked from the other way... why should you be able to work with something invalid just because the method is private? Doesn't make sense, right? Always try to use defensive programming and you will be happier in life ;-)
This is a question of preference. But consider instead why are you checking for null or rather checking for valid input. It's probably because you want to let the consumer of your library to know when he/she is using it incorrectly.
Let's imagine that we have implemented a class PersonList in a library. This list can only contain objects of the type Person. We have also on our PersonList implemented some operations and therefore we do not want it to contain any null values.
Consider the two following implementations of the Add method for this list:
Implementation 1
public void Add(Person item)
{
if(_size == _items.Length)
{
EnsureCapacity(_size + 1);
}
_items[_size++] = item;
}
Implementation 2
public void Add(Person item)
{
if(item == null)
{
throw new ArgumentNullException("Cannot add null to PersonList");
}
if(_size == _items.Length)
{
EnsureCapacity(_size + 1);
}
_items[_size++] = item;
}
Let's say we go with implementation 1
Null values can now be added in the list
All opoerations implemented on the list will have to handle theese null values
If we should check for and throw a exception in our operation, consumer will be notified about the exception when he/she is calling one of the operations and it will at this state be very unclear what he/she has done wrong (it just wouldn't make any sense to go for this approach).
If we instead choose to go with implementation 2, we make sure input to our library has the quality that we require for our class to operate on it. This means we only need to handle this here and then we can forget about it while we are implementing our other operations.
It will also become more clear for the consumer that he/she is using the library in the wrong way when he/she gets a ArgumentNullException on .Add instead of in .Sort or similair.
To sum it up my preference is to check for valid argument when it is being supplied by the consumer and it's not being handled by the private/internal methods of the library. This basically means we have to check arguments in constructors/methods that are public and takes parameters. Our private/internal methods can only be called from our public ones and they have allready checked the input which means we are good to go!
Using Code Contracts should also be considered when verifying input.
I am attempting to build (for learning purposes) my own event logger; I am not interested in hearing about using a non-.net frameworks instead of building my own as I am doing this to better understand .net.
The idea is to have an event system that I can write out to a log file and/or pull from while inside the program. To do this I am creating an LogEvent class that will be stored inside of a Queue<LogEvent>.
I am planning on using the following fields in my LogEvent class:
private EventLogEntryType _eventType //enum: error, info, warning...
private string _eventMessage
private Exception _exception
private DateTime _eventTime
What I am not sure is the best way to capture the object that caused the event to be called. I thought about just doing a private Object _eventObject; but I am thinking that is not thread safe or secure.
Any advice on how to best store the object that called the event would be appreciated. I am also open to any other suggestions you may have.
Thanks, Tony
First off, nothing wrong with writing your own. There are some good frameworks our there, but sometimes you reach the point where some bizarre requirement gets you rolling your own, I've been there anyway...
I don't think you should be using text messages. After doing this type of logging in several projects, I have come the the conclusion that the best approach is to have a set of event types (integer IDs) with some type of extra information field.
You should have an enum of LogEvetTypes that looks something like this:
public enum LogEventTypes
{
//1xxx WS Errors
ThisOrThatWebServiceError = 1001,
//2xxx DB access error
//etc...
}
This, from my experience will make your life much easier when trying to make use of the information you logged. You can also add an ExtraInformation field in order to provide event instance specific information.
As for the object that caused the event, I would just use something like typeof(YourClass).ToString();. If this a custom class you created, you can also implement a ToString override that will name sense in your logging context.
Edit: I am adding several details I wrote about in the comments, since I think they are important. Passing objects, which are not immutable, by ref to service methods is generally not a good idea. You might reassigne the same variable in a loop (for example) and create a bug that is near-impossible to find. Also, I would recommend doing some extra work now to decouple the logging infrastructure from the implementation details of the application, since doing this later will cause a lot of pain. I am saying this from my own very painful experience.
I have a method for pulling data from a database, and I want it to get this:
Limit of Five entries,
Item type is Newsletter,
Needs to be active (PublishDate < DateTime.Now)
So I'm thinking of naming it GetFiveActiveNewslettersByCreatedDate()
This seems a little long to me. I looked on the site for a good way to name things like this, how would you handle it?
How about something like this instead?
public IEnumerable<Newsletter> GetActiveNewsletters(int maxRecords = 5)
{
// ...
}
Top 5 is still the default, but it's not overly specific anymore.
The reason I would avoid baking "five" into the name, personally, is what it might mean down the line.
For example, what if later, there were some demand for 10 newsletters in certain scenarios instead of 5? Well, you'd create an additional method GetTenActiveNewslettersByCreatedDate(). And now, you have a 'design pattern' that subsequent developers will follow when 20, 50, 100 newsletters are needed. This is a design that will rot, and you can stave it off now by parameterizing the five.
Of course, this might be YAGNI/speculative generality. If 5 really is some kind of magic, hard-fast, will never change rule, then you might cautiously bake it in. I just find that I've regretted doing and seeing things like that far, far more often than not.
I would recommend renaming it to: GetNewsletters(int recordCount=5)
The number of newsletters would be a parameter for the method.
The rest could be assumed and described in the ///Summary.
To avoid this specific naming I would think about making the method generic. Something like:
GetNewsLetters(int amount, bool onlyActive, SortOrder orderBy)
Name it so that it is evident to any developer what the method does. Self commenting code is king. If your method name gets too long, you're probably doing too many different things inside of it and would be a candidate for refactoring.
As for your specific example, I don't have a problem with the name you've given.
I would add parametrized method, like
GerEntries(T typeofEntity, DateTime date, int maxNumber)
And naturaly document method with comments
I am trying to work up an error and logging framework, and while I think I have the errors well in hand at this point, I'm a little more sketchy some other things by virtue of having never tackled the problem before. The part I'm having most trouble with right now is trace messages, which are obviously not the same thing as outright errors and shouldn't be handled the same way. Of course, when I try to think about the way they should be handled, I draw a blank.
What are some things that you've found helpful in your trace messages, whether for debugging or filtering things later? Obviously, there are some things like the level (Info, Alert, Warn, Critical), the message, the AppDomain, but what else?
For a little background to the setup, the logging framework I'm working on will live in our application class libraries and put information into a database table, MSMQ line, or flat logging file (application configurable).
Please DO NOT suggest ready-made products like log4net, the Enterprise Library, ELMAH, or anything like that as answers to this question. We have already considered each popular addition and discarded them as not useful to our needs. If you'd like to suggest pieces of data from these products that's fine, but a lot of places I've asked for input on get hung up on recommending things that we have spent weeks vetting and discarding instead of answering the question. I am hoping Stack will show some more class.
For logging purposes I'd consider including the user logged in, timestamp and domain specific information (which you'll have to decide for yourself). For trace messages for debugging, I'd include the class/method and values of variables and parameters that could be troublesome.
I like to use the pattern of using different trace levels for things that "belong" in those levels. For example, in the case of a web service which handles requests and federates other requests out to other servers, i might log the fact that i received a request as 'Informational', whereas i might print out the contents of the full request as 'Verbose'.
I basically categorize different types of events with different levels, sprinkle various levels throughout the codebase, and then consumers of the framework / product can choose 'Verbose' mode to see every last parameter of each request and response object, vs 'Informational' to simply be able to see the flow of requests / responses.
Obvoiusly erroneous events ( non- OK status code received ), based on their severity, should either be a 'Warning' or an 'Error'. I like to think of things that cause the process to abort ( e.g. all external servers are down, i can't possibly fulfil your request ) as 'Error' worth, and things that are worth noting but don't interrupt workflow ( e.g. 1 replica of external server is unavailable or it's round trip response exceeds some latency threshold ) as 'Warning' worthy.
Some additional cool things i've done is put a method in your Logger implementation that automatically knows who the caller of the Logger.WriteLine(...) is and prints it accordingly:
/// <summary>
/// Any additional layers between this log class and calling classes will cause
/// this stack trace to return incorrect 'calling' method name
/// </summary>
/// <returns></returns>
private static string GetCallingMethod()
{
var stack = new StackTrace();
var className = string.Empty;
var methodName = string.Empty;
foreach ( var frame in stack.GetFrames() )
{
className = frame.GetMethod().DeclaringType.FullName;
methodName = frame.GetMethod().Name;
if ( className != typeof( Logger ).FullName )
{
break;
}
}
return string.Format( "{0}.{1}", className, methodName );
}
I think some of this depends on what your applications do. For example if your application is database intensive I would think you would definitely want to log your sql statements. Any dynamic input from the user can also be helpful as debug logging. Datestamps are always helpful when looking at logs. Stacktraces on errors like others have mentioned. There are other instances but these are a couple. I'm curious though about why you ruled out ready made products like log4net etc. If you asked this question before online I'd be curious to see links.
When using System.Diagnostics TraceSource for logging/tracing, is there a difference between using TraceSource.TraceTransfer and TraceSource.TraceEvent(TraceEventType.Transfer, ... ?
In our environment, we will be developing a number of services that will communicate via WCF. We are also evaluating what platform we should use for logging/tracing. We are leaning towards using System.Diagnostics, at least in part because of the ability to correlate logs between services using the CorrelationManager, ActivityID, TraceTransfer etc.
I can see in the documentation for TraceSource that it has a TraceTransfer method as well as a TraceEvent that can take TraceEventType.Transfer as an event type. When would you use one vs the other? I have seen examples like here that show how to use Start/Stop and how to manage the ActivityID and CorrelationManager, but I have rarely seen anyone use TraceSource.TraceEvent(TraceEventType.Transfer, ... ). There is an example here that shows using TraceEventType.Transfer (as well as explicitly calling TraceTransfer).
By this point, maybe I am actually starting to answer my own question...
It seems like TraceSource.TraceTransfer is explicitly doing something with the ActivityID that is passed as a parameter whereas calling TraceSource.TraceEvent(TraceEventType.Transfer, ...) is not explicitly doing anything with the ActivityID (since it is not passed as a parameter). It seems like it is really just logging another event, that happens to be a Transfer event, but does not do anything else with the CorrelationManager or anything else.
Thanks for any help.
According to the MSDN documentation for TraceSource.TraceTransfer, TraceSource.TraceTransfer calls TraceListener.TraceTransfer. The base implementation of TraceListener.TraceTransfer simply calls TraceListener.TraceEvent(TraceEventType.Transer, ...), passing a string representation of the guid passed to TraceSource.TraceTransfer.
So, it seems to me that TraceSource.TraceTransfer provides way to explicitly indicate that an activity transfer is happening. At the call site, it is more obvious and more typesafe to use TraceSource.TraceTransfer. If implementing a TraceListener, you could take advantage of the explicit TraceTransfer call and the fact that the activity id is passed in as a Guid to do any special work that you want to do when an activity id is transferred.