|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
On Oct 13, 11:38 pm, jtorjo2...@yahoo.com wrote:
> > > Since your process_msg_type determines the interface of how to > > log, no library would be able to rely on there being a unified > > interface. This is the motivation for the toast::log::log_handle > > That is ok - the way you log (the Usage Syntax) is really up to you - > I don't want to enforce that on the users of the lib. > As a matter of fact, the previous version of the lib (which was > rejected) - had a unified interface - and that was considered bad by > the boost community ![]() I think I probably explained my one point too much in my previous message The whole point of my message really was simply to ask forany boost::logger to provide a feature that allows me to pass in any logger type to a library at runtime, without that library knowing the - exact templatized type- of the logger when it was compiled. Just about everything in my message other than this feature request was simply my description of what I think are natural consequences of providing this feature. If you can get around them somehow, that's great. But I think that in order to provide this feature you must provide a basic interface that will never change. That's not to say that it can't be customized for the applications direct use, but there must be a basic interface there somewhere. > > Obviously there is a run > > time penalty for the type erasure, but it is a much smaller penalty > > than having to recompile all your libraries whenever you change your > > concrete logger, and there is no penalty at all for the application > > I know I haven't addressed compilation times yet - it's on my TODO> list ![]() It's not the compilation time that matters, it's the fact that I as a library writer may not have given you the source code to recompile at all. And yet it would still be useful for me to provide an interface that will accept some boost::logger for me to log to it. > > application level. A consequence of this suggestion is that you must > > standardize on logging levels as well (which means you should add a > > I don't like that - what if you don't want to use levels? It should be > your option, not enforced by the lib. Again I think this is a natural consequence of being able to pass - some logger- into a library. You don't require that the application pay attention to these levels, or even that the levels are mandatory for logging a message in the basic interface, simply that they exist for the library to use should they choose. There is a fundamental disconnect between the application and the library, there is simply no way to at application compile time tell the library the details about the logger type, some minimal details need to be known ahead of time. > > As a general comment, I really don't like the idea of the macro's. > > Especially as short as you recommend, which certainly can't go in any > > headers, so they need to be repeated in every source file, which means > > I'm not particularly fond of macros myself - but I believe logging is > definitely one of those scenarios where you really need them. > Otherwise, how do you suggest implementing efficient logging? That is, > writing to a log, only if it's enabled. In the toast::logger, I provide two functions, message and forced_message. message is safe and does the check on your behalf, forced_message logs regardless leaving you responsible for doing the check. I think that efficient logging is very important, it's one of the primary motivations for my having written the toast::logger, but it's only important sometimes. The most convenient interface possible is the most important the rest of the time. > Also, macros can go in headers - why not? > In my apps, I usually have a header called log.h or app_log.h, where I > define the logs of the application, and any other macros I might need. > That's a perfect place to define your application' macros. The point I was trying to make is that there can be no convenient standard macros, every client of your library uses their own hand crafted macro, so there is no consistency. > > I think if the > > message processing and gathering were made efficiently enough, and the > > interface simple enough, the motivation for macro's would go away. Of > > I don't quite share this... Even if you can always say something like: > > if ( g_l) g_l->str() << "repeating this " << "can be cumbersome"; > > ...it'll still be cumbersome on the users of your log. > > But in fact - using macros is up to you, so if you're happy with > writing like shown above, who am I to force you into using macros? why make me use macros to have a convenient syntax?? Why not: log << INFO << "this is a " << "convenient syntax"; This can be made reasonably efficient, although it does increase the checks from one to one for every <<. > > > course not all the overhead can be removed without that surrounding > > if, but a lot can, and then users can always surround the message with > > an if in the case that a profiler tells them to. > > Not sure I understand... If the convenient syntax I mentioned just above is in your critical path (i.e. your profiler tells you logging is slowing you down), then I can surround it with an if: if(log.check(INFO)) // confirm that info messages will be logged: log << INFO << "good old " << "convenient syntax"; I would only do this if necessary for performance. And if it was necessary a LOT, then I might consider writing a macro. I think that recommending macros from the start though is not a great idea, and I think that you should provide the convenient interface without the macros. > > I also wasn't completely comfortable with the method of overriding > > library types. I think this method would make my suggested goal very > > difficult to implement. I haven't thought of a suggestion for you > > yet. > > Why? Well I don't like the dependence on order. It also seems like you can't have loggers of different char types in the same unit for example. I'm not sure how you would reconcile this with the feature I'm requesting to be able to pass a logger to libraries. I still haven't had time to think of all the reasons I don't like it, or of a suggestion for how to replace it though ![]() > > As a C++ expert, you should know better than to provide and implicit > > conversion to bool ![]() > > Why not? If you plan on not using macros, it's a blessing ![]() implicit conversion to bool can cause all sorts of unexpected conversions. Better to use an 'unspecified-bool-type' like a pointer to member function. struct A { typedef (void A::*unspecified_bool_type)(bool); bool enabled; void set(bool b) { enabled = b } operator unspecified_bool_type() { return enabled ? &A::set : 0; } }; This will convert in all the right places (like in the condition to an if). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
First of all, sorry for the late reply - I really missed this message.
Need to buy that pair of glasses ![]() > > I think I probably explained my one point too much in my previous > message The whole point of my message really was simply to ask for> any boost::logger to provide a feature that allows me to pass in any > logger type to a library at runtime, without that library knowing the - > exact templatized type- of the logger when it was compiled. > > Just about everything in my message other than this feature request > was simply my description of what I think are natural consequences of > providing this feature. If you can get around them somehow, that's > great. But I think that in order to provide this feature you must > provide a basic interface that will never change. That's not to say > that it can't be customized for the applications direct use, but there > must be a basic interface there somewhere. I don't agree with forcing this here. Note: I do provide all the needed things for *you* to do this, if you truly want. I haven't completed the docs, but you can check out the code ![]() (it's the logger<gather_msg,default_> class). Also, if you want to try this, please take the latest code from SVN. On another note, you can give me a clear scenario, and I'll include it in the docs - with an example as well :P We can continue this talk off list - you can find my email address on my site. > > > I know I haven't addressed compilation times yet - it's on my TODO> > list ![]() > > It's not the compilation time that matters, it's the fact that I as a > library writer may not have given you the source code to recompile at > all. And yet it would still be useful for me to provide an interface > that will accept some boost::logger for me to log to it. Again, my lib allows for that. If you - as a *client* of my lib, want to provide for this, you can certainly do it - no problem. > > I don't like that - what if you don't want to use levels? It should be > > your option, not enforced by the lib. > > Again I think this is a natural consequence of being able to pass - > some logger- into a library. You don't require that the application > pay attention to these levels, or even that the levels are mandatory > for logging a message in the basic interface, simply that they exist > for the library to use should they choose. There is a fundamental > disconnect between the application and the library, there is simply no > way to at application compile time tell the library the details about > the logger type, some minimal details need to be known ahead of time. I would assume that the fact that you use levels or not has a big impact on your application/and how you present this to your clients. > > > > As a general comment, I really don't like the idea of the macro's. > > > Especially as short as you recommend, which certainly can't go in any > > > headers, so they need to be repeated in every source file, which means > > > I'm not particularly fond of macros myself - but I believe logging is > > definitely one of those scenarios where you really need them. > > Otherwise, how do you suggest implementing efficient logging? That is, > > writing to a log, only if it's enabled. > > In the toast::logger, I provide two functions, message and > forced_message. message is safe and does the check on your behalf, > forced_message logs regardless leaving you responsible for doing the > check. I think that efficient logging is very important, it's one of > the primary motivations for my having written the toast::logger, but > it's only important sometimes. The most convenient interface possible > is the most important the rest of the time. > Fine by me If you want to force logging, just use the logger objectdirectly (instead of a macro). However, I don't really think it should be the programmer's choice to force logging a message. This choice should be somehow centralized, and eventually changing this should be able at runtime. And again, if you really want to force logging a message - not a problem, just ignore the filter :P > > Also, macros can go in headers - why not? > > In my apps, I usually have a header called log.h or app_log.h, where I > > define the logs of the application, and any other macros I might need. > > That's a perfect place to define your application' macros. > > The point I was trying to make is that there can be no convenient > standard macros, every client of your library uses their own hand > crafted macro, so there is no consistency. Again, this was asked by others You can't satisfy everyone.And I don't see a problem with this - usually you'll use "<<" to do logging. Most of the people will probably use this, but there will be a few which need a different interface - they will have their reason. I'm gonna let them ![]() >From my previous lib I did learn something : everyone has their own idea of how a logging lib should look like. It's really hard to satisfy a majority ![]() > > > if ( g_l) g_l->str() << "repeating this " << "can be cumbersome"; > > > ...it'll still be cumbersome on the users of your log. > > > But in fact - using macros is up to you, so if you're happy with > > writing like shown above, who am I to force you into using macros? > > why make me use macros to have a convenient syntax?? Why not: > > log << INFO << "this is a " << "convenient syntax"; > > This can be made reasonably efficient, although it does increase the > checks from one to one for every <<. This is a really no no - because you don't want to pay for calling time-consuming function(s) if the message will not be logged: LDBG_ << "some msg " << some_time_consuming_func(); Also, defining you macros is rather easy, and the only difference from what you've shown, is that you'll have some macro as the first word: // or something similar LINFO_ << "this is a " << "convenient syntax"; Please check out the scenarios and their code, to see how simple it is to create your own macros: http://torjo.com/log2/doc/html/common_scenarios.html > > > If the convenient syntax I mentioned just above is in your critical > path (i.e. your profiler tells you logging is slowing you down), then > I can surround it with an if: > > if(log.check(INFO)) // confirm that info messages will be logged: > log << INFO << "good old " << "convenient syntax"; > > I would only do this if necessary for performance. And if it was > necessary a LOT, then I might consider writing a macro. I think that > recommending macros from the start though is not a great idea, and I > think that you should provide the convenient interface without the > macros. I'm not a big fan of this. Here's why: if people will know that logging will happen no matter what, most C++ programmers will think twice before logging something - you'll end up with just too little logged info. Knowing that logging can be turned off is a big relief ![]() However, it's not that hard to allow users to do logging without macros. > > > > As a C++ expert, you should know better than to provide and implicit > > > conversion to bool ![]() > > implicit conversion to bool can cause all sorts of unexpected > conversions. Better to use an 'unspecified-bool-type' like a pointer > to member function. That's doable However, I have completely separated logger fromfilter concepts. So there's no operator bool() anymore :P Best, John -- http://John.Torjo.com -- C++ expert .... call me only if you want things done right -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
![]() |
| Outils de la discussion | |
|
|