drdobbs.com
Open in
urlscan Pro
172.67.66.43
Public Scan
Submitted URL: http://drdobbs.com/cpp/201804215
Effective URL: https://drdobbs.com/cpp/logging-in-c/201804215
Submission: On December 28 via manual from NZ — Scanned from NZ
Effective URL: https://drdobbs.com/cpp/logging-in-c/201804215
Submission: On December 28 via manual from NZ — Scanned from NZ
Form analysis
1 forms found in the DOMGET /sitesearch
<form method="get" action="/sitesearch">
<input type="hidden" name="sort" value="publishDate desc">
<ul>
<li><input type="text" value="" size="40" id="queryText" name="queryText" maxlength="100" class="text"></li>
<li><input type="submit" value=" " class="search"></li>
</ul> Search: <input type="radio" name="type" value="site" checked=""> Site <input type="radio" name="type" value="sourcecode"> Source Code
</form>
Text Content
This site uses cookies to provide you with the best user experience possible. By using Dr. Dobb's, you accept our use of cookies. × Informa Dr. Dobb's is part of the Informa Tech Division of Informa PLC * Informa PLC * About us * Investor relations * Talent This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726. Welcome Guest | Log In | Register | Benefits * Subscribe * Newsletters * Digital Library * RSS * * Search: Site Source Code * Home * Articles * News * Blogs * Source Code * Webinars & Events * * Sections ▼ * Home * Articles * News * Blogs * Source Code * Webinars & Events * Cloud * Mobile * Parallel * .NET * JVM Languages * C/C++ * Tools * Design * Testing * Web Dev * Jolt Awards Channels ▼ * Cloud * Mobile * Parallel * .NET * JVM Languages * C/C++ * Tools * Design * Testing * Web Dev * Jolt Awards C/C++ Share Reddit Permalink LOGGING IN C++ By Petru Marginean, September 05, 2007 11 Comments Logging is a critical technique for troubleshooting and maintaining software systems. Petru presents a C++ logging framework that is typesafe, thread-safe, and portable. Logging is a critical technique for troubleshooting and maintaining software systems. It's simple, provides information without requiring knowledge of programming language, and does not require specialized tools. Logging is a useful means to figure out if an application is actually doing what it is supposed to do. Good logging mechanisms can save long debugging sessions and dramatically increase the maintainability of applications. In this article, I present a simple—but highly useful—logging framework that is typesafe, threadsafe (at line-level), efficient, portable, fine-grained, compact, and flexible. The complete source code, which works with Visual C++ 7.1, g++ 3.3.5, and CC 5.3 on Sun and other platforms, is available in the DDJ October 2007 zip file at www.ddj.com/code/. In Part 2 of this article, I enhance this technique by providing more granularity. THE FIRST STEP Let's take a first stab at a Log class. Listing One uses an std::ostringstream member variable called "os" to accumulate logged data. The Get() member function gives access to that variable. After all data is formatted, Log's destructor persists the output to the standard error. You use Log class like this: Log().Get(logINFO) << "Hello " << username; Executing this code creates a Log object with the logINFOx logging level, fetches its std::stringstream object, formats and accumulates the user-supplied data, and finally, persists the resulting string into the log file using exactly one call to fprintf(). Why flush during destruction? The last two steps are important because they confer threadsafety to the logging mechanism. The fprintf() function is threadsafe, so even if this log is used from different threads, the output lines won't be scrambled. According to gnu.org/software/libc/manual/html_node/Streams-and-Threads.html: LISTING ONE // Log, version 0.1: a simple logging class enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4}; class Log { public: Log(); virtual ~Log(); std::ostringstream& Get(TLogLevel level = logINFO); public: static TLogLevel& ReportingLevel(); protected: std::ostringstream os; private: Log(const Log&); Log& operator =(const Log&); private: TLogLevel messageLevel; }; std::ostringstream& Log::Get(TLogLevel level) { os << "- " << NowTime(); os << " " << ToString(level) << ": "; os << std::string(level > logDEBUG ? 0 : level - logDEBUG, '\t'); messageLevel = level; return os; } Log::~Log() { if (messageLevel >= Log::ReportingLevel()) { os << std::endl; fprintf(stderr, "%s", os.str().c_str()); fflush(stderr); } } The POSIX Standard requires that by default the stream operations are atomic...issuing two stream operations for the same stream in two threads at the same time will cause the operations to be executed as if they were issued sequentially. The buffer operations performed while reading or writing are protected from other uses of the same stream. To do this, each stream has an internal lock object that has to be (implicitly) acquired before any work can be done. Before moving on to a more efficient implementation, let's write code to insert tabs in proportion to the logging level, and append an std::endl to each chunk of text. This makes the log line oriented and easy to read by both humans and machines. Here's the relevant code: Log::ReportingLevel() = logDEBUG2; const int count = 3; Log().Get(logDEBUG) << "A loop with " << count << " iterations"; for (int i = 0; i != count; ++i) { Log().Get(logDEBUG1) << "the counter i = " << i; } which outputs: - 22:25:23.643 DEBUG: A loop with 3 iterations - 22:25:23.644 DEBUG1: the counter i = 0 - 22:25:23.645 DEBUG1: the counter i = 1 - 22:25:23.645 DEBUG1: the counter i = 2 Indentation makes the logging more readable. More leading tabs imply a more detailed level of logging. 1 2 3 4 Next RELATED READING * News * Commentary NEWS * JetBrains Upsource 1.0 Final Release * Mirantis Releases Free Developer Edition * Jelastic Docker Integration For Orchestrated Delivery * Mac OS Installer Platform From installCore More News» COMMENTARY * Things That Go Boom * JetBrains Upsource 1.0 Final Release * Mirantis Releases Free Developer Edition * Parasoft DevTest Shifts To Continuous More Commentary» * Slideshow * Video SLIDESHOW * Jolt Awards 2014: The Best Utilities * The Most Underused Compiler Switches in Visual C++ * Developer Reading List * Jolt Awards: Coding Tools More Slideshows» VIDEO * Jimmy'll See You Around * IBM Mobile Developer Challenge * IBM Five in Five Predictions * Teen Computer Scientist Wins Big at ISEF More Videos» * Most Popular MOST POPULAR * RESTful Web Services: A Tutorial * Lambda Expressions in Java 8 * Developer Reading List: The Must-Have Books for JavaScript * Why Build Your Java Projects with Gradle Rather than Ant or Maven? More Popular» -------------------------------------------------------------------------------- MORE INSIGHTS WHITE PAPERS * Modernize your Security Operations with Human-Machine Intelligence * The Rise of Extended Detection & Response More >> REPORTS * Zero Trust and the Power of Isolation for Threat Prevention * Forrester Total Economic Impact Study: Team Cymru Pure Signal Recon More >> WEBCASTS * Cybersecurity Tech: Where It's Going and How To Get There * Developing an Effective Threat Intelligence Program for Your Enterprise More >> -------------------------------------------------------------------------------- INFO-LINK * * * * CURRENTLY WE ALLOW THE FOLLOWING HTML TAGS IN COMMENTS: SINGLE TAGS These tags can be used alone and don't need an ending tag. <br> Defines a single line break <hr> Defines a horizontal line MATCHING TAGS These require an ending tag - e.g. <i>italic text</i> <a> Defines an anchor <b> Defines bold text <big> Defines big text <blockquote> Defines a long quotation <caption> Defines a table caption <cite> Defines a citation <code> Defines computer code text <em> Defines emphasized text <fieldset> Defines a border around elements in a form <h1> This is heading 1 <h2> This is heading 2 <h3> This is heading 3 <h4> This is heading 4 <h5> This is heading 5 <h6> This is heading 6 <i> Defines italic text <p> Defines a paragraph <pre> Defines preformatted text <q> Defines a short quotation <samp> Defines sample computer code text <small> Defines small text <span> Defines a section in a document <s> Defines strikethrough text <strike> Defines strikethrough text <strong> Defines strong text <sub> Defines subscripted text <sup> Defines superscripted text <u> Defines underlined text Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities. To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy. Login or Register to Comment arsemik I do not understand why we log at destructor. ThorstenR136 This still is the best startup / tutorial for a logger in C++. Simple, extendable and well documented. I used this as a base framework and integrated logging from a calling Python interpreter to merge C++ and Python log. I learned a lot about simplicity in logging. Too much log4xyz monsters flying around, where you need a training before writing a single line to the log. CCsernica Late reply is late, but I only ran across this just now while looking to save myself from work writing a logging facility for a new app. If you were to dynamically create an instance of the Log class and use that for all your logging throughout your application, what you say here would be correct. However, using the macro as presented, the object automatically created goes out of scope as soon as you exit the if-else statement where it exists. The destructor is therefore called immediately. Dollar_cz EasyLogging++ is the way to go that is fast light weight an high performing with extra features! mstokes357 I like this log facility. I made one change that adds some value for me. I added a logNONE enum at the first position (index=0) with the idea that it would not be used to log to. If used when setting the ReportingLevel() none of the log entries will be printed. daffodil nice .......... ildar I am not going to say that this is not the (one) way of doing it. However, there is one issue here. It seems that all logs has been appended to the string, and at the end of the life of application that string is written to the file. Is that 'buffering" taken to extreme? Does some one really wants to allow the log to be accumulated in the application memory indefinitly? twerd Great little header file. Im using it as a simple logger for some research Im doing. One small problem I had was that static boost::mutex mtx inside the Output2File class refused to compile and gave me a linker error. I moved it out of the class as a global static variable and that fixed it. grunt I can't open logcpp.zip which is no suprise since the file's size is only 44 Bytes. And the "0710.zip" download link doesn't seem to work for me. UK Click the "0710.zip" instead, it contains the logcpp.zip, too. voodooRod Having trouble unzipping this file. C/C++ RECENT ARTICLES * Dr. Dobb's Archive * Jolt Awards 2015: Coding Tools * Building Node.js Projects in Visual Studio * Building Portable Games in C++ * C# and .NET's Sudden Ubiquity MOST POPULAR Stories Blogs * The C++14 Standard: What You Need to Know * A Simple and Efficient FFT Implementation in C++: Part I * State Machine Design in C++ * Lambdas in C++11 * A Lightweight Logger for C++ * * * C++11: unique_ptr * C++11's async Template * Abstractions For Binary Search, Part 10: Putting It All Together * It's Hard To Compare Floating-Point Numbers * Auto Types and Range-Based For Statements in C++11 * * THIS MONTH'S DR. DOBB'S JOURNAL This month, Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android , and much more! Download the latest issue today. >> UPCOMING EVENTS Live Events WebCasts * [FREE VIRTUAL EVENT] 9/29 - Enterprise Network Evolution & Modernization - * [FREE Virtual Event] The Identity Crisis - Understanding Cyber Attacks on Remote Workers Making Deception a Part of Your Enterprise Defense Strategy A Black Hat Webinar: Inside the Cyber Safety Review Board: A Fireside Chat with Jeff Moss, Chair Rob Silvers and Deputy Chair Heather Adkins Streamlining Your Patch Management Processes Developing an Effective Threat Intelligence Program for Your Enterprise More Webcasts>> FEATURED REPORTS What's this? * Incident Readiness and Building Response Playbook * Privileged Access Management Checklist * Proven Success Factors for Endpoint Security * Intel 471 Breach Report * SANS 2021 Cloud Security Survey More >> FEATURED WHITEPAPERS What's this? * Quantifying the Gap Between Perceived Security and Comprehensive MITRE ATT&CK Coverage * Defending Corporate Executives and VIPs from Cyberattacks * The Cyber Threat Impact of COVID-19 to Global Business * Identity Access Management 101 * The Impact of XDR in the Modern SOC More >> MOST RECENT PREMIUM CONTENT Digital Issues 2014 Dr. Dobb's Journal * November - Mobile Development * August - Web Development * May - Testing * February - Languages Dr. Dobb's Tech Digest * DevOps * Open Source * Windows and .NET programming * The Design of Messaging Middleware and 10 Tips from Tech Writers * Parallel Array Operations in Java 8 and Android on x86: Java Native Interface and the Android Native Development Kit 2013 * January - Mobile Development * February - Parallel Programming * March - Windows Programming * April - Programming Languages * May - Web Development * June - Database Development * July - Testing * August - Debugging and Defect Management * September - Version Control * October - DevOps * November- Really Big Data * December - Design 2012 * January - C & C++ * February - Parallel Programming * March - Microsoft Technologies * April - Mobile Development * May - Database Programming * June - Web Development * July - Security * August - ALM & Development Tools * September - Cloud & Web Development * October - JVM Languages * November - Testing * December - DevOps Discover more from Informa Tech * InformationWeek * Interop * Dark Reading * Data Center Knowledge * Network Computing * IT Pro Today Working With Us * Contact Us * About Us * Advertise * Reprints Follow Dr. Dobb's on Social * * * * * Home * Cookie Policy * CCPA: Do not sell my personal info * Privacy * Terms Copyright © 2022 Informa PLC. Informa PLC is registered in England and Wales with company number 8860726 whose registered and head office is 5 Howick Place, London, SW1P 1WG. Techweb