Write a daemon on Windows (4) Log the rest

Source: Internet
Author: User

Write a daemon on Windows (4) Log the rest

This time I said everything else related to the journal.

First, Vaformat

C + + log interfaces usually have two forms: stream input form, printf form.

I use the printf format because the stream input is not well controlled.

printf form requires the log interface to support variable length parameters, I do not directly in the log implementation class support variable length parameters, but only accept a string parameter, you can see the first article.

Why is it?

If you want to be a variable length parameter, that's it.

bool log_string (constconstchar, constintconst  Char *s, ...);

So in every log_xxx variant you have to write _vsnprintf_s that set of code, and is exactly the same (I do not know whether __VA_ARGS__ macros can be passed), this is obviously bad practice.

I put the processing of indefinite parameters in the macro definition, similar to:

#define Errorlog (S, ...) _log (Log_error, __file__, __line__, Vaformat (Max_log_buffer, S, __va_args__))

Vaformat is the processing of variable length parameters:

std::string vaformat (constconstchar* msg, ...); Std::wstring Vaformat (constconst wchar_t* wmsg, ...);

Because you do not know how long it takes to format it, you specify the maximum length and truncate if the length after formatting is greater than the maximum length. Vaformat also has a little trick, when the specified max_size is less than 1024, use the stack space, otherwise request heap memory, which is from the implementation of std::string--sso short string optimization.

Can look at the implementation of the Vaformat, two versions of the code basically the same, this is certainly not good, but I do not know how to merge them together, this is a todo. A similar problem is also below.

Second, Clasterrorformat

This thing is used to solve the problem of the record LastErrorCode mentioned in the first article.

Its main function is to convert the error code into a written description, and the appropriate construct can also omit GetLastError invocation:

classClasterrorformat: Publicboost::noncopyable{ Public: Clasterrorformat (): M_code (GetLastError ()) {} Clasterrorformat (ConstDWORD Code): M_code (code) {}~Clasterrorformat () {} Public:    ConstDWORD Code ()Const    {        returnM_code; }    ConstSTD::string&str () {//...    }    Conststd::wstring&wstr () {//...    }Private:    //...};

The corresponding interface in the Log implementation class:

bool log_last_error (constconstchar, constintconst std::string& prefix);

Accept a Clasterrorformat reference, and then record the error code and its corresponding description in the log: XXX, error code:999, error msg:yyy

The final log interface is available in two versions: one accepts a clasterrorformat parameter, and the other is omitted, constructed within the function itself.

Third, Str_encode

I can not in the log file a wide string, one will remember the narrow string, then can not see, and considering the size of the log file, I finally decided to follow the narrow string systemcurrentcodepage (on the Simplified Chinese version of Windows, is GB2312) encoded log , so I'm going to convert it to a narrow string for a wide string.

Windows provides two APIs for encoding conversions: MultiByteToWideChar and WideCharToMultiByte, and these two APIs are always called two times for a safe conversion. I encapsulated it a little bit and made two functions:

Std::wstring multistr2widestr (constintCONST std::string& s); std::  string widestr2multistr (constintconstconstChar * Default_char = NULL);

Note: The code page encoding for Systemcurrentcodepage is CP_ACP.

This will always be a bit slower when remembering wide strings, so I use narrow strings in my code where I can use narrow strings.

Iv. Any_lexical_cast

The code is always unavoidable to do type conversion, especially to convert the number into a string, in order to be simple, I used the boost lexical_cast, although everyone said the goods inefficient, because the use of C + + flow, but I adhere to the "first correct, then optimize" principle, or use it.

However, the use of this thing has two inconveniences:

1. Throws an exception when the conversion fails

2. converting bool to string is 0 or 1, not true or false

In order to solve these two problems, I made a second package:

1. When the conversion fails, the padding is the default value. Caller must provide default value

2. Special conversions between BOOL and string

This is any_lexical_cast:

Template<typename Target, TypeName source>Target Any_lexical_cast (Constsource& SRC,Consttarget&fail_value) {Target value=Fail_value; Try{Value= boost::lexical_cast<target>(SRC); }    Catch(boost::bad_lexical_cast&) {Value=Fail_value; }    returnvalue;} Template<>BOOLany_lexical_cast<BOOL, std::string> (ConstSTD::string& SRC,Const BOOL&fail_value); template<>BOOLany_lexical_cast<BOOL, Std::wstring> (Conststd::wstring& SRC,Const BOOL&fail_value); template<>std::stringANY_LEXICAL_CAST&LT;STD::string,BOOL> (Const BOOL& SRC,ConstSTD::string&); template<>std::wstring Any_lexical_cast<std::wstring,BOOL> (Const BOOL& SRC,Conststd::wstring&);

Please refer to the source code for specific implementation.

Wu, Cselfpath

The log initialization interface usually needs to provide a path parameter to specify the log storage path. I added a default path: When passing an empty string, the log file is placed in the log directory of the path where the application is located, and if the log directory does not exist, it is created first.

Get the path to the application can be placed inside the log module, but in consideration of other places may also be used, and once the application is started, the path will not change, so a singleton class Cselfpath is made.

Cselfpath only calls GetModuleFileNameA once in the constructor to get the path and split it into directories, filenames, and so on.

Vi. Cloggerimpl and Logger

The implementation of the log there are a lot of things I don't want to see for callers, typically members of private, and the interface of the log implementation class is not easy to use. So I have introduced an indirect layer logger between the log implementation class and the caller, and its main function is to hide the log implementation class and make the interface more "pro-people". Of course, besides this, I gave it some other features: control the log output level. Logger is not a class.

Vii. Disable 3rd Party Library Warning

When I was using boost about string algorithm, I found that the compiler would be a big warning from the use of std::copy in the Boost library, and I know exactly what the Boost library code is. These warnings are more and more annoying, is there a safe way to eliminate this warning?

There must have been:

#pragma warning (push)#pragma warning (disable:4996)<boost/algorithm/string .hpp>#pragma warning (pop)

The above code is saved as a header file: Boost_algorithm_string.h. If you want to include BOOST/ALGORITHM/STRING.HPP later, use Boost_algorithm_string.h instead.

Source: Https://git.oschina.net/mkdym/DaemonSvc.git (Master) && Https://github.com/mkdym/DaemonSvc.git (for lifting).

Sunday November 1, 2015

Write a daemon on Windows (4) Log the rest

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.