[Pharo-dev] Logging API discussion

Tudor Girba tudor at tudorgirba.com
Tue Apr 26 09:36:05 EDT 2016


Hi Dennis,


> On Apr 26, 2016, at 3:26 PM, Denis Kudriashov <dionisiydk at gmail.com> wrote:
> 
> Hello.
> 
> I resumed discussion about SystemLogger and Beacon here http://forum.world.st/What-the-state-of-unifying-Beacon-with-SystemLogger-td4890684.html. 
> I plan to unify both approaches by saving traditional terminology from SystemLogger and cool features from Beacon.

Thanks for your effort, but as I said before, the decision was to integrate Beacon and iterate on that.


> Let's think about logging API to log any object in the system. Most natural way is just send message #log to object itself:
> 
> anObject log
> 
> It would be nice replacement for Object>>logCr.

This type of usage should be discouraged in my opinion. We should instead encourage people to use typed logging signals, like we should also discourage people from using
	self error: ‘a magic string here’.


> But when we log some information we usually want to log it with little remark, importance level and (most important) timestamp. This information is kind of standard for logging domain. But it requires much more methods for logging API.
> So we need extra information to put together with objects:
> 	• timestamp
> 	• user message
> 	• importance level (debug, info, error, etc.)

Please do not do that. This might make sense for C or Java (although it does not), but we have objects and we should filter based on those without relying on a rigid system based on random levels. Please.


> 	• whatever (process hash, process name for example)
> 	• sometimes it can be needed to put in log something different than object itself. (for example it can be just copy of object to not change state of log entry during app lifetime)
> Here is possible API based on Object extensions. It has drawbacks but it is good to think about it too:

No. This is the responsibility of the subtypes of Signal.


> "it will put anObject in logs with default #info level"
> anObject log 
> 
> "it will put anObject in logs with default #info level and given user message"
> anObject logWith: 'something interesting was happened with anObject’ 

>  "inside block we can put any logging domain information from application and also override content by specific representation"
> anObject logBy: [:logEntry |
>       logEntry message: 'something interesting to be saved with our object'
>       logEntry content: anotherObject] "here logs with interest about anObject will receive logEntry with anotherObject instead of anObject” 

This will just favor more strings. We want to move away from them.


> And similar for different kind of levels:
> 
> anObject logForDebug.
> anObject logForDebugWith: 'some debug message'
> anObject logForDebugBy: [:logEntry | ]
> 
> anObject logAsError.
> anObject logAsError: 'object computation was wrong'
> anObject logAsErrorBy: [:logEntry | ]
> And most general:
> 
> anObject logAs: LogLevel warn
> anObject logAs: LogLevel warn with:  'something interesting'
> anObject logAs: LogLevel warn by: [:logEntry | ]


I am definitely against this.


> And in case of classic logging with strings only first expressions would be used:
> 
> 'some info message' log.
> 'some debug message' logForDebug
> 'some error message' logAsError
> 'some warn message' logAs: LogLevel warn
> 
> Problem with this approach: it pollutes Object with 12 extra methods and it can be more. So maybe it is better to use current SystemLogger API based on class Log: 
> 
> Log info: anObject
> Log info: anObject as: 'computation result'        "as example"
> Log info: anObject as: [:logEntry | 
> logEntry message: 'something interesting to be saved with our object
> logEntry content: anotherObject]
> 
> Log error: anObject
> Log error: anObject as: 'computation was wrong''
> Log error: anObject as: [:logEntry | ]
> 
> Comparing to original SystemLogger versions I separate user message from object content. It makes possible to log any object with extra user message.
> But anyway it not feels very well IMHO. And it requires three methods for each log level. Maybe we can put this methods into LogLevel itself:
> 
> Log info add: anObject
> Log info add: anObject as: 'computation result'
> Log info add: anObject as: [:logEntry | 
> logEntry message: 'something interesting to be saved with our object
> logEntry content: anotherObject]
> 
> Log error add: anObject
> Log error add: anObject as: 'computation was wrong''
> Log error add: anObject as: [:logEntry | ]
> 
> And we can make short version for default logging level (which can be object specific):
> 
> Log add: anObject
> Log add: anObject as: 'computation result'
> Log add: anObject as: [:logEntry | ]
> 
> That's all. I hope we can produce best suitable API for object logging. Then we can think how to adopt SystemLogger or Beacon for it.
> Also think about this API in context that we can register specific loggers for specific objects and specific importance level.

I think this is the wrong approach and I am opposing this direction in the most constructive way I can :).

Cheers,
Doru


> Best regards,
> Denis

--
www.tudorgirba.com
www.feenk.com

"Don't give to get. Just give."









More information about the Pharo-dev mailing list