The diary of the world's fastest, most flexible, and most robust C++ logging API library.
Monday, November 8, 2010
Wide String Shims for std::exception
The new release of STLSoft supports seamless use of exceptions with Pantheios (and FastFormat) in wide-string builds; described on this post on the STLSoft project blog.
Labels:
exceptions,
FastFormat,
Pantheios,
STLSoft,
widestring
Pantheios 1.0.1 beta 198 released: new i and xi inserters
The latest release of Pantheios includes two new inserters, pantheios::i and pantheios::xi. The former is a typedef for the pantheios::integer inserter class, and may be used interchangeably with it:
produces the same output (and effectively the same binary) as:
The latter is actually a new class, and is used specifically for inserting integers in hexadecimal form, optionally specifying minimum width:
The (hopefully obvious) advantage to both these new inserter types is that they're more succinct. There are more to come ...
#include <pantheios/inserters/i.hpp>
#include <pantheios/pan.hpp>
int n = 10;
pan::log_DEBUG("i=", pan::i(n));
pan::log_DEBUG("i=", pan::i(n, -10));
pan::log_DEBUG("i=", pan::i(n, -10, pan::fmt::hex));
produces the same output (and effectively the same binary) as:
#include <pantheios/inserters/integer.hpp>
#include <pantheios/pan.hpp>
int n = 10;
pan::log_DEBUG("i=", pan::integer(n));
pan::log_DEBUG("i=", pan::integer(n, -10));
pan::log_DEBUG("i=", pan::integer(n, -10, pan::fmt::hex));
#include <pantheios/inserters/xi.hpp>
#include <pantheios/pan.hpp>
int n = 16;
pan::log_DEBUG("i=", pan::xi(n));
pan::log_DEBUG("i=", pan::xi(n, -10));
The (hopefully obvious) advantage to both these new inserter types is that they're more succinct. There are more to come ...
Tuesday, November 2, 2010
User blogs about "Pantheios Basics"
Just to let you know, a user has kindly posted a tutorial Pantheios logging library - basic blog entry, which covers the basics of obtaining, installing, and using the Pantheios library.
I've just scanned it, and it looks like it covers quite a lot of stuff.
I'll read it fully soon, and post any more relevant news.
Thanks, Son DN!
I've just scanned it, and it looks like it covers quite a lot of stuff.
I'll read it fully soon, and post any more relevant news.
Thanks, Son DN!
Saturday, October 30, 2010
Choosing severity levels
A recent enquiry on the Pantheios Help Forum requested guidance for what severity levels to use in what circumstances. Although I've a strong opinion on this, which I'll include in a series of articles on diagnostic logging that I'm currently preparing for Dr. Dobbs (and which I hope will see publication over Dec-Feb), I'm happy to volunteer the basic ideas here.
Although Pantheios can be used with any range severity levels that fits into the int type - which usually means 32- or 64-bits, depending on platform - as it ships Pantheios defines eight stock severity levels, corresponding to the eight levels defined by SysLog, as follows:
Briefly, we treat these levels as follows. (Note, the terminology introduced in the first and second parts of my Quality Matters column for ACCU's Overload will be helpful in several instances.)
I hope that's been helpful.
Although Pantheios can be used with any range severity levels that fits into the int type - which usually means 32- or 64-bits, depending on platform - as it ships Pantheios defines eight stock severity levels, corresponding to the eight levels defined by SysLog, as follows:
Syslog level | Pantheios level (C) | Pantheios level (C++) | Integer value |
---|---|---|---|
Emergency | PANTHEIOS_SEV_EMERGENCY | pantheios::emergency | 0 |
Alert | PANTHEIOS_SEV_ALERT | pantheios::ealert | 1 |
Critical | PANTHEIOS_SEV_CRITICAL | pantheios::critical | 2 |
Error | PANTHEIOS_SEV_ERROR | pantheios::error | 3 |
Warning | PANTHEIOS_SEV_WARNING | pantheios::warning | 4 |
Notice | PANTHEIOS_SEV_NOTICE | pantheios::notice | 5 |
Info | PANTHEIOS_SEV_INFO | pantheios::info | 6 |
Debug | PANTHEIOS_SEV_DEBUG | pantheios::debug | 7 |
Briefly, we treat these levels as follows. (Note, the terminology introduced in the first and second parts of my Quality Matters column for ACCU's Overload will be helpful in several instances.)
- Emergency is used for (attempting to) record contract violations, i.e. the firing of an active runtime contract, indicating that the program is now behaving in contradiction to its design. According to the principle of irrecoverability, a program in this state must immediately terminate, and thus it is possible to see an emergency level message being the last, or one of the last, messages in the diagnostic logging sequence of a program that has faulted.
- Alert is used for (attempting to) record practically-unrecoverable conditions, e.g. out of memory. It is customary to see an alert level message being the last, or one of the last, messages in the diagnostic logging sequence of a program that has ended processing in a non-normative manner.
- Critical and error are used for conditions that usually indicate that the normative behaviour of the program cannot be achieved. There is some ambiguity as to the exact distinction to draw between them, and I'm still in two minds about it. Obviously, critical is more severe, and may be associated with conditions more likely to result in program failure than does those designated as error.
- Warning is used for recording warning conditions.
- Notice is used for logging information that is to be displayed in "normal" operation, e.g. "database connection achieved"
- Informational is used for logging information that is useful when actively monitoring the health of a system, but that is not necessarily displayed as part of "normal" operation. Ideally it should be possible to turn on all logging of this level without exceeding the program's performance criteria.
- Debug is used for debugging statements. Note that one of the important advanges of using Pantheios is that its high efficiency means that you don't have to make decisions about eliding certain statements at compile-time; they can instead be made at runtime, which is appropriate. Using Pantheios means eliminating #ifdef DEBUG from application code, forever!
I hope that's been helpful.
Labels:
alert,
critical,
debug,
emergency,
error,
informational,
notice,
Pantheios,
quality matters,
severity levels,
syslog,
warning
Monday, October 18, 2010
Pantheios 1.0.1 beta 197 released: pantheios::integer inserter now more disciplined in width behaviour when hex formatting
The latest release of Pantheios provides substantial reworking of the pantheios::integer inserter class, including how it handles minimum-width specifiers when formatting in hex. Previously, as a statement such as
would have resulted in the output of a line such as:
[old_int_hex.4312, 19/10/2010 7:38:53.062 AM; Debug]: n= 13
With the (surprisingly involved!) changes in 1.0.1 beta 197, the line produces output such as:
[old_int_hex.488, 19/10/2010 7:45:24.625 AM; Debug]: n=0x13
Note the absence of the two spaces - between n= and 13 - that were previously associated with expanding 13 to a minimum width of four. (Anyone who's used printf() can guess how that came about.)
Since these are only minimum widths, this change is unlikely to upset any log processing, but it's possible, so be advised.
#include <pantheios/inserters/integer.hpp>
#include <pantheios/pan.hpp>
int n = 0x13;
pan::log_DEBUG("n=", pan::integer(n, 4, pan::fmt::hex));
pan::log_DEBUG("n=", pan::integer(n, 4, pan::fmt::hex));
would have resulted in the output of a line such as:
[old_int_hex.4312, 19/10/2010 7:38:53.062 AM; Debug]: n= 13
With the (surprisingly involved!) changes in 1.0.1 beta 197, the line produces output such as:
[old_int_hex.488, 19/10/2010 7:45:24.625 AM; Debug]: n=0x13
Note the absence of the two spaces - between n= and 13 - that were previously associated with expanding 13 to a minimum width of four. (Anyone who's used printf() can guess how that came about.)
Since these are only minimum widths, this change is unlikely to upset any log processing, but it's possible, so be advised.
Labels:
hex,
inserter,
Pantheios,
pantheios::integer,
printf
Pantheios 1.0.1 beta 197 released: be.file supports date/time in log file name
The latest release of Pantheios provides an enhancement to the be.file back-end, supporting current-date and/or current-time to form part of the log file-name. For example,
pantheios_be_file_setFilePath("test-%T-%D.log");
The %T specifier is replaced by the current time, in the format HHMMSS. The %D specifier is replaced by the current date, in the format YYYYMMSS. If the function is called at, say, 7:22 am (and 10 seconds) on the 19th October 2010, the process will log to the file test-20101019-072210.log.
(Note, as always, the following caveat: Pantheios' stock back-ends are intended for tutorial or simple program purposes. More sophisticated logging should be provided by having Pantheios delegate its transport to a fully-fledged logging library.)
#include <pantheios/backends/bec.file.h>
pantheios_be_file_setFilePath("test-%T-%D.log");
The %T specifier is replaced by the current time, in the format HHMMSS. The %D specifier is replaced by the current date, in the format YYYYMMSS. If the function is called at, say, 7:22 am (and 10 seconds) on the 19th October 2010, the process will log to the file test-20101019-072210.log.
(Note, as always, the following caveat: Pantheios' stock back-ends are intended for tutorial or simple program purposes. More sophisticated logging should be provided by having Pantheios delegate its transport to a fully-fledged logging library.)
Friday, March 26, 2010
b 196 imminent: full wide-string support
Title pretty much says it all. Am swamped - what's new - with commercial activities, but am hoping to get this out over the coming weekend.
Thursday, March 4, 2010
Pantheios 1.0.1 beta 195 released: enhanced pantheios::w2m inserter
The latest release of Pantheios provides enhanced flexibility for the pantheios::w2m inserter class. As well as passing wide C-strings, as in:
the new facilities allow passing wide string class instances, as in:
and
Previously, the log statement would have to explicitly elicit the C-string pointer and the length, as in:
Obviously, this is far less expressive than the new facilities.
void f(wchar_t const* s)
{
pan::log_DEBUG("f(s=", pan::w2m(s), ")");
. . .
}
the new facilities allow passing wide string class instances, as in:
void f(std::string const& s)
{
pan::log_DEBUG("f(s=", pan::w2m(s), ")");
. . .
}
and
void f(stlsoft::simple_wstring const& s)
{
pan::log_DEBUG("f(s=", pan::w2m(s), ")");
. . .
}
Previously, the log statement would have to explicitly elicit the C-string pointer and the length, as in:
void f(stlsoft::simple_wstring const& s)
{
pan::log_DEBUG("f(s=", pan::w2m(s.data(), s.length()), ")");
. . .
}
Obviously, this is far less expressive than the new facilities.
Monday, February 15, 2010
Pantheios 1.0.1 beta 194 released: new pantheios::slice inserter
The first update of Pantheios in six months, 1.0.1 (beta 194), has just been released. It contains various mods and fixes, but the main changes are:
In such a case, you cannot just pass str to a log statement, because that assumes it will be nul-terminated, and the semantics of fn() are clearly that it's not. In most circumstances you will get a benign overrun. But that is not guaranteed, and it's possible to get an access violation by overrunning into an invalid area of address space. (Imperfect C++ discusses ways in which this can happen.)
So, instead, use the new pantheios::slice inserter:
Now only the requisite slice will be included.
But there's more to it than just that. I often use the convention of naming parameters when logging function entry, as in:
Obviously this is done explicitly, with names contained in the literal strings that are used to separate the function parameters in such cases. The question with pantheios::slice, then, is how we would achieve the same?
To accomodate this, pantheios::slice has several overloads that facilitate naming. Assuming str is "abcdefghijklm" and len is 5, consider the following examples:
- addition of the new pantheios::slice inserter
- widestring compatibility (of source, not yet of makefile build targets)
void fn(char const* str, size_t len)
{
. . .
In such a case, you cannot just pass str to a log statement, because that assumes it will be nul-terminated, and the semantics of fn() are clearly that it's not. In most circumstances you will get a benign overrun. But that is not guaranteed, and it's possible to get an access violation by overrunning into an invalid area of address space. (Imperfect C++ discusses ways in which this can happen.)
So, instead, use the new pantheios::slice inserter:
// assumes inclusion of pantheios/pan.hpp
// assumes inclusion of pantheios/inserter/slice.hpp
void fn(char const* str, size_t len)
{
pan::log_DEBUG("fn(", pan::slice(str, len), ")");
. . .
Now only the requisite slice will be included.
But there's more to it than just that. I often use the convention of naming parameters when logging function entry, as in:
void fn2(std::string const& path1, std::string const& path2)
{
pan::log_DEBUG(path1=", path1, ", path2=", path2, ")");
. . .
Obviously this is done explicitly, with names contained in the literal strings that are used to separate the function parameters in such cases. The question with pantheios::slice, then, is how we would achieve the same?
To accomodate this, pantheios::slice has several overloads that facilitate naming. Assuming str is "abcdefghijklm" and len is 5, consider the following examples:
void fn(char const* str, size_t len)
{
// gives "fn(abcde)"
pan::log_DEBUG("fn(", pan::slice(str, len), ")");
// gives "fn(str=abcde, len=5)"
pan::log_DEBUG("fn(", pan::slice(str, len, "str", "len"), ")");
// gives "fn(s;abcde;l:5)"
pan::log_DEBUG("fn(", pan::slice(str, len, "s", "l", ":", ";"), ")");
. . .
Sunday, February 14, 2010
LoadLibrary() and ERROR_NOACCESS
Further to my last post, if you muck up the initialisation and there's an access violation in your DLL, you'll likely see ERROR_NOACCESS from GetLastError() when LoadLibrary() fails.
Thursday, February 11, 2010
Don't forget to initialise the library!
I'm doing some work for an overseas client at the moment, on a Windows DLL that provides access to their business logic to Excel. We're working on tightening up the implementation, ready for product release.
Most of the work so far has been porting between C/C++ compilers, but one of the other things I'm doing is adding diagnostic logging, via Pantheios of course.
As it's been several months since I've plugged Pantheios into a DLL I've forgotten the significant issues:
Most of the work so far has been porting between C/C++ compilers, but one of the other things I'm doing is adding diagnostic logging, via Pantheios of course.
As it's been several months since I've plugged Pantheios into a DLL I've forgotten the significant issues:
- (By default) the Pantheios core is not initialised explicitly, meaning that DllMain() must call the functions pantheios_init() (if C) or pantheios::init() (if C++) to initialise the library (or handle the error and fail DllMain(), if it fails), and call pantheios_uninit() (if C) or pantheios::uninit() (if C++) to uninitialise (but only if the initialisation failed). (See instructions below for implicit initialisation in a DLL.)
- Global object constructors must not invoke logging facilities
- specify the pre-processor flag PANTHEIOS_FORCE_AUTO_INIT in your DLL's compilation
- have at least one C++ source file the DLL project includes pantheios/pantheios.hpp
Labels:
back-end,
Initialisation,
Initialization,
Pantheios
Subscribe to:
Posts (Atom)