Thursday, November 6, 2014

Write your logger in C++

While writing any decently big software, you will in most cases dump messages at various points in the software to capture important events or issue warnings and errors. You typically do this by adding printfs, cout's, cerr's etc. and all of this works pretty fine. But, what if tomorrow you want to dump all messages in a log file instead of pushing them on stdout or you want to do some processing over all the messages like adding a message code in the header or replacing all the end-of-line characters with just a space etc. Well, you can say that I will go over all the places where the messages are being dumped and easily adapt them - works, but can be immensely cumbersome and error-prone. Why not do something that's elegant, maintainable and less error-prone? Why not use the power unleashed by C++? Why not create a logger class that unveils a convenient and flexible interface to dump messages. Following is an example of such a class:

#include <iostream>
#include <fstream>
#include <string>
class MyLogger
{
public:
    // 2nd bit tells that you need to push to a file too
    enum LoggingMode { NORMAL=0, FILE_ONLY=2, TEE_MODE=3 };

    MyLogger(bool is_err=false) {
        m_Mode = NORMAL;
        m_fLogErrorStream = is_err;   
    }

    ~MyLogger() {
        if ((int)m_Mode & 2) m_OutFile.close();
    }

    void initFile(const std::string& outfile)  {  
        m_Mode = FILE_ONLY; // set the m_Mode to file mode  
        m_OutFile.open(outfile.c_str(), std::ofstream::out | std::ofstream::app);
    }

    void setMode(const LoggingMode& mode)
    {
        m_Mode = mode;
    }

    template <typename T>
    MyLogger& operator << (const T& val) {
        out() << val;
        if ((int)m_Mode & 2) fout() << val;
        return *this;
    }
    
private:
    LoggingMode m_Mode;
    bool m_fLogErrorStream;
    std::ofstream m_OutFile;
  
    std::ostream& fout() {
        return m_OutFile;   
    }
    std::ostream& out() {
        if (m_fLogErrorStream) return std::cerr;      
        return std::cout;
    }

};
To keep the interface of the logger C++like, operator << is overloaded. The operator is implemented as a function template whose specialized versions would be generated by the C++ compiler based on the types of the argument it is applied to. Based on the LoggingMode, the MyLogger class decides whether to log to usual streams (i.e. stdout or stderr) or to a file only or to both. The enum LoggingMode can be extended to support other modes. Following is a simple test for this class and it works:
MyLogger mlog;
int x = 100; float y = 6.67;
mlog.initFile("test.log");
mlog.setMode(MyLogger::TEE_MODE);
mlog << "Hello World!!\n";
mlog << "Value of x and y is: " << x << ", " << y << "\n";
In this test, the arguments to operator << were the usual types viz. const char*, int and float. Let's try other things that are typically given to the cout/cerr objects like 'std::endl', 'std::flush', 'std::hex' etc. popularly known as manipulators. All these manipulators are basically functions (or function pointers) and can also match to the operator << function template - hence, no further extensions should be needed. But, that's not entirely true - for example, consider the std::endl function that has the following prototypes:
ostream& endl (ostream& os);

template <class charT, class traits>
basic_ostream<charT,traits>& endl (basic_ostream<charT,traits>& os);
Now when you have a statement like 'mlog << std::endl', the compiler will be left confused when trying to resolve the type 'T' for std::endl as it will have 2 ambiguous choices.Hence, it will bail out giving the errors as shown below (using MSVC 2010 compiler):
error C2914: 'MyLogger::operator <<' : cannot deduce template arg as function arg is ambiguous
error C2676: binary '<<' : 'MyLogger' does not define this operator or a conversion to a type
acceptable to the predefined operator
So, how do we fix this? We know that we need to choose the first prototype as that corresponds to 'ostream', so let's add a specialization for operator <<, that will help the compiler zero-in on the first prototype:
MyLogger& operator << (std::ostream& (*manip)(std::ostream&)) {
#if DEBUG
    if (manip == std::endl) {
        std::cout << "endl found!\n";
    }
#endif
    manip(out());
    if ((int)m_Mode & 2) manip(fout());
    return *this;
}
With this specialized implementation of operator << added, the compiler is now able to resolve the ambiguity and we get the desired result!

Sunday, June 26, 2011

got hitched!

All the way from the moon, down she landed on my floor,
Draped with innocence & charm -
Dusky damsel she, knocked my door!
Oblivious and lost, I moved towards the door & it switched,
Awestruck with her gaze -
Revived later, only to find myself hitched!!


Past 7 months were, as if I was caught in a 'time warp' - lot of things changed, including my status (as title says) ;-) and my car, my hairdo to name a few..Time's now slowly de-warping and I am back to my usual chores..
BTW today, I completed 50 days of my nuptials and also 5 years in software industry - nice day to get back to posting!
..signing off now as dinner's calling

Sunday, December 26, 2010

All world's a stage! - Shakespeare

Incidentally, while browsing the web, I came across the following monologue from Shakespeare:

All the world's a stage,
And all the men and women merely players;
They have their exits and their entrances;
And one man in his time plays many parts,
His acts being seven ages. At first the infant,
Mewling and puking in the nurse's arms;

.. [Read full text at http://www.artofeurope.com/shakespeare/sha9.htm]

Here, he visualizes the whole world as a stage and a life as a play. Though, I had heard about this comparison of Shakespeare earlier, but never read this original speech/poem of his. What impresses me most is that he serves the truth "as is" on your platter - without any garnishing!

These lines definitely reminds me of the other lines "hum sab to rang-manch ki katputliaan hain.." from the eternal movie 'Anand' which still reverberates in the heart of Indian cinema.

Sunday, November 14, 2010

Million Dollar Baby

I always fantasized to be a pugilist almost since my childhood; but, of course never pursued it for obvious reasons. Now, I satiate my thirst by just watching boxing matches and movies related to the same; be it the Rocky series or the Cindrella Man (James J Braddock), I 've seen 'em all. The one movie that was eluding me from quite a few years, was - 'Million Dollar Baby', that stars Hillary Swank (Maggie Fitzgerald) in a memorable role of a woman pugilist (got an Oscar for her performance), Clint Eastwood (Frankie Dunn) as a trainer and Morgan Freeman (Eddie) as a retired Boxer, at his usual best.
I just loved all the boxing sequences in the movie; all were shot very real and were quite captivating. In addition to the fights, what appealed to me the most was the way in which the development of the bond between the boxer and the trainer was shown. Also, very interesting and touchy dialogs between Swank, Eastwood and Freeman. A few of them, I am quoting below (picked from imdb):

[After Maggie gets hit, lies paralyzed & asks Frankie to relieve her from her life]
Maggie Fitzgerald: I do have one favor to ask of you boss.
Frankie Dunn: Anything you want.
Maggie Fitzgerald: Remember what my daddy did for Axel?
Frankie Dunn: [long pause] Don't even think about that.
Maggie Fitzgerald: I can't be like this, Frankie. Not after what I've done. I've seen the world. People chanted my name. Well, not my name... some damn name you gave me. But they were chanting for me. I was in magazines. You think I ever dreamed that'd happen? I was born two pounds, one-and-a-half ounces. Daddy used to tell me I'd fight my way into this world, and I'd fight my way out. That's all I wanna do, Frankie. I just don't wanna fight you to do it. I got what I needed. I got it all. Don't let 'em keep taking it away from me. Don't let me lie here 'till I can't hear those people chanting no more.

[Frankie feels sorry for allowing Maggie to fight to a boxer of higher category to win World Championship]
Frankie Dunn: It wasn't fault. I was wrong to say that.
Eddie Scrap-Iron Dupris: You damn right. I found you a fighter. You made her the best fighter she could be.
Frankie Dunn: I killed her.
Eddie Scrap-Iron Dupris: Don't say that. Maggie walked through that door with nothing buts guts. No chance in the world of being what she needed to be. It was because of you that she was fighting the championship of the world. You did that. People die everyday, Frankie - mopping floors, washing dishes and you know what their last thought is? I never got my shot. Because of you Maggie got her shot. If she dies today you know what her last thought would be? I think I did all right.


[Frankie finally relieves her]
Frankie Dunn: [to Maggie] All right. I'm gonna disconnect your air machine, then you're gonna go to sleep. Then I'll give you a shot, and you'll... stay asleep. Mo cuishle means "My darling, my blood."

And, performances by all three of them was exceptional; And I couldn't spot any directorial flaw in my first watch!

Sunday, August 1, 2010

Impoverished of Values..

Oblivious to the songs of innocence from the birds at the dawn,
With our brains brimmed with craftiness, cagey plans we spawn;

Unlearning the virtue of altruism taught by the benevolent trees,
At all incidences, when the world needs our help, we just freeze;

Not absorbing even a fraction of endurance evinced by mother earth,
We often lose our temper for most trifling reasons, sheerly unworth;

Still unkempt, after bathing in the honest rays emanated by the sun,
Unfazed, with ease, satiating our greed, we bluff in our profession;

Unfeeling the warmth and love in the air, brought by gentle zephyr,
We indulge into brawls, germinate hatred, just to fulfil a diddly desire!

I penned the above lines, just to highlight the loss that we are accepting unknowingly. If these values are gone, then we'll be no more than faulty machines!

Monday, March 15, 2010

'Science' buried in 'Mines'

Talking to a science student in India can be very depressing - Why ? Because, the knowledge that he supposedly has, is pretty superficial. While, he is aware of the hefty terms, but in most cases, is ignorant of their significance in real world. He can talk about the laws of thermodynamics, but you will find him lost, when being asked to apply them in reality. Similarly, students of Mathematics will not know the real-life applications of topics like Complex numbers, PDEs etc. nor will they be be aware of the real-life problems that led to the evolution of these branches in Mathematics. More importantly, they are unaware of this deficiency of theirs! Thats the reason why, India doesn't produces good research in basic Sciences!
But, I don't believe that students are the only one to be blamed.. Equally blameworthy are the teachers, available facilities and also our education system.
Practically, teachers should in addition to just rushing through the syllabus (which the most only do), put in some effort in germinating the interest of students in the subject. In my whole education life, I 've seen only a couple of teachers who used to do this! One main reason that teachers don't do this effectively, is that in India, most teachers are teachers just for the sake of job and not by interest; this is because the teaching job here, is not a very lucrative option. I feel happy that recently, there has been a revision in the salaries of teachers; this should definitely encourage those who actually have a penchant, to go for teaching. I would really appreciate if similar action is followed for the scholarships of the students pursuing Ph.D.
Coming to facilities inside colleges in India, they are obviously not up to the mark. Lack of equipment in labs, does play a significant role in diminishing the interest of students in the subject. The funding from Government to the institutions needs to improve in terms of amount and also it should be ensured that it is effectively utilized.
The Education system of a country shouldn't be stringent, but should be strong and should be reachable. It should be strong enough to not let an undeserving student get through and also vice-versa. It should not be so stringent, that a person interested in X is forced to read Y, just because Y is considered to be an important subject or reading Y will increase job prospects etc. LBNL, the system should ensure that education reaches to all. If we juxtapose all these requirements against our education system, we can clearly see the loop-holes in it.
Well, all of these factors, definitely contributes to my perception about a Science student in India and also provide an explanation of the current state of research in basic sciences in India...I really hope this changes soon!

Tuesday, March 2, 2010

Weekly Status

Most Software Engineers will empathize with Dilbert here ;-) On a serious note, while many maintain such fantasies, only a few make a break-through to actually live them.