About | Examples | Performance | Structure | Extensibility | Download |
About IVJLogger | |||||
IVJLogger is a small library of classes and functions written in Java designed to assist you with your logging needs. "Why another logger?" you may ask. Well, the main purpose of it is keeping it simple. Simplicity means less bugs, more extensibility, better performance, and happier users. Many loggers I've seen out therer take forever to set up, I am not even talking about all the initialization code, and all the clean-up you have to do just to get them to log one line of code. With IVJLogger you don't need any external files, no clean-up, and initialization code is as simple as instantiating an object. Here's a summary of the best features that make IVJLogger what it is:
Advanced features include multi-threading and monthly and yearly archivation of old files (this happens automatically, without you EVER having to worry about it). |
|||||
Back to the menu | |||||
Examples | |||||
Here's an example that demonstrates how easy it is to use IVJLogger. If you want more insights on the structure of IVJLogger, see extensibility section.S
Of course, in a real-life situation, it'd be more like this: (in this example I used LogManger instead of Logger; see extensibility section for details)
Besides these examples, I also included an example application ('src/ivj/logging/Example.java'), which emulates some kind of an on-line server. Go through the code and modify file locations in the constructor so that they fit your need. Then simply compile and test. Here's what you get: [HTML trace] [Exceptions log]. There are more examples at the extensibility section. So, as you can see, IVJLogger is quite simple to use. However, that's not the only thing that deserves it the IVJ marking... read on to find out about other great features that it comes with! |
|||||
Back to the menu | |||||
Performance | |||||
Although performance wasn't the main target of IVJLogger, unsurprisingly, it turned out to be one of its greatest features. I believe it's the result of simple design that makes coding clearer and results more efficient. There are two classes that are used for real logging: ArchivedFileLogger and ArchivedHTMLLogger, and both of them are extremely efficient. Before I go into numbers, I must note that I would not be surpirsed if most other loggers work faster than IVJLogger. The catch is that IVJLogger sits in the background with minimal-priority thread pool and collects messages into a queue and writes them when your program isn't doing anything. This means that it doesn't take away any performance from your program (unlike some other loggers that write "10000 lines per second" while your program's performance's trashed). Well, time for the numbers. I don't see any point of giving you thorough statistics, because they will only belong to my computer's configuration. So, instead, I included a PerformanceTest class that will allow you to see how fast what loggers will work on your system. Simply open up that file in the 'src/ivj/logging/PerformanceTest.class' and go through the code. Comments will explain most of the things, but just in case:
For the busy investors, the numbers on my machine (P4 2000Mhz IBM DDYS SCSI 36GB HDD 1GB RAM):
Pretty good for a logger that doesn't take away performance from your program, ain't it? :) |
|||||
Back to the menu | |||||
Structure | |||||
This part goes into details about the structure of IVJLogger and how would you go about extending it to fit YOUR needs. First of all, I should say that ease of extension was one of the primary goals of IVJLogger, and I believe I have achieved it. So, here we go... There are two primary interfaces that control the entire flow: Logger and LogManager. Loggers play the role of doing the actual logging: in case of FileLogger, it has to open the output stream, format the message, write it, and close the output stream. LogManagers' role is to keep Loggers "under the hood" and dispatch data between them. In other words, LogManagers keep a list of all the Loggers that were assigned to them, and whenever you request them to log something, they iterate through the list, and give every logger a reference to that message. If you're confused right now, that's good. We'll look at the structure in a real-life situation later on, right now I want to describe what Loggers and LogManagers come with IVJLogger. Here's a list of Loggers:
Here's a list of LogManagers:
Now that you know what kind of loggers and log managers there are, let's see how they cooperate in a real-life example.
We are making some stupid GUI program, that we'll sell to the users. It's not finished yet, but we'll sell it anyway, and in case users get crashes, we want to find out the cause... So, we want to keep track of few things:
We also want to have a simple trace in the console... just for the hell of it. One thing is for sure: we'll be using ThreadedLogManager, since it's a commercial program, and we want the user to get as much as possible (haha), and as we know, it's the most efficient log manager there is. So, first we need to initialize the log manager, which will hold different Loggers and dispatch messages between them:
Now, we want to add a logger that will give us a trace in the console. Luckily, we have a ConsoleLogger, so we do the following somewhere in the constructor:
Now, let's think of a logger that will record every click that a user makes... We can choose between HTML and plain text... I'd stick with the beauty... Do we need to archive? Yes I think so... in case user uses this thing for years (yeah right :)), we want to easily find any time location, so let's go with ArchivedHTMLLogger:
There's one more logger left - the exceptions logger. There are two approaches we can take:
Second option sounds better, but there's a few difficulties:
So, I am going to stick with the first approach (just like I did in the Example program ('src/ivj/logging/Example.java')). Since this is going to be a separate logger, we may declare it alone, without any LogManager. But that means we won't take advantage of the ThreadedLogManager, which makes everything smoother, faster, and nicer. So here's what we'll do:
And add a logger in the constructor:
I decided to use ArchivedFileLogger instead of ArchivedHTMLLogger because... no reason. I think Exceptions look better in naked text than HTML. Ok, so what have we created so far: a 'log' LogManager with a console logger and a movement logger, and an 'exceptions' log manager where we'll put all our exceptions. Now, the program part. Whenever you have an exception, here's what you have to do:
Whenever you have some kind of a button click or a text enter, you'd do the following:
And that's all you have to do to have 100% professional and efficient logigng in your program. Remember, ThreadedLogManager is thread safe, so you can really pump data into it from all over the place, and it'll just take it in and barf it out (into a file, of course :)). I hope after reading this section you understand how LogManagers and Loggers cooperate. If you're still confused, look over PerformanceTest and Example programs... they're well documented and they demonstrate everything. Also, don't hesitate to look at the source... It's not rocket science. |
|||||
Back to the menu | |||||
Extensibility | |||||
Now it's time to talk about extensibility. There are many cases when this might come in handy, but usualy it'd be used purely for filtering out whatever. Remember, you can extend Loggers as well as LogManagers... and it is ENCOURAGED. This section assumes you've read the structure section and understand the realtionship between loggers and log managers. So, suppose you want to have a logger that only logs exceptions, and nothing else. This may sound familiar, since we had the same problem in the structure section, but this time we're going to take a different approach. What we want to do, is to extend a logger (in our case, FileLogger), and to intercept every message that's about to get logged. Then we need to see if that message is an exception, and if it is, then we'll let it through. Sounds like a lot of work huh? You'd be surpised how simple it is, though. In fact, it's so simple, I am going to paste the code right in:
... Comments say it all. Now, all you'll have to do to add that Logger to your main LogManager:
And then log as normally.. Is that simple or what? You can do the exact same thing with LogManager - I'd suggest extending ThreadedLogManager and overriding its log(int,Object) method. Same as the code above, only change some names. There is, of course, an annonymous-class approach, that looks something like this:
Well, this section was short, wasn't it? It's because that's pretty much all there is to IVJLogger. Simplicity, simplicity, simplicity... |
|||||
Back to the menu | |||||
Download | |||||
So you've read everything and now you're drooling all over your keyboard thinking how much you gonna have to pay for this thing? Heh I know you're not drooling and I know that you know that its free since its hosted by SourceForge.net :). So, here's some links: Author: Ivan Jouikov (ivj@comcast.net) SF page: IVJLogger // download the most recent version from there |
|||||
Back to the menu |