2016-04-27 20:50 GMT+02:00 stepharo <[hidden email]>: why? What I am talking about is that I don't want create MySpecialLog for any MySpecialDomainObject which I want to log. |
2016-04-28 10:13 GMT+02:00 Denis Kudriashov <[hidden email]>:
Traits? Put you logging api in a Trait instead of Object and let your MySpecialDomainObject use this trait ? |
In reply to this post by stepharo
2016-04-27 20:50 GMT+02:00 stepharo <[hidden email]>:
And for my example when I want mark ThisContextSignal with extra user message how I can achieve it? |
In reply to this post by Nicolai Hess-3-2
2016-04-28 10:20 GMT+02:00 Nicolai Hess <[hidden email]>:
Really? Try remember usual workflow when we investigate some problems with code when we can't use debugger. We put kind of "Transcript show:" in multiple places to see state of our objects at concrete point of time. With object logging we will log our objects directly without converting to strings. Do you want to stop your "debugging workflow" every time you need to log objects which not support it? (to add special trait). But anyway with Trait you can't add timestamp to your domain object which is always required for logs (I think we all agree about timestamp). |
In reply to this post by Denis Kudriashov
Hi Denis,
> On Apr 27, 2016, at 2:16 PM, Denis Kudriashov <[hidden email]> wrote: > > 2016-04-27 10:43 GMT+02:00 Norbert Hartl <[hidden email]>: > I must confess I cannot follow you completely. What we were/are talking about is that the assumption a logging entry needs timestamp, log level and such is not appropriate. If you have legacy syslog style logging in mind it appears natural but for a lot of use cases it is not. > > Could you provide example where it is not? I just did a project in which I needed to understand a real-time parallel system that had 3 layers of abstractions. The code already had in place a log system based on log levels. If I opened the #debug level, I would get a ton of information, even though I wanted to focus on exactly one layer, or sometimes only one a certain type of leg entries. This is a common place scenario and it is time we can pick events based on their nature. The numbered layers come from languages where false=0, so let’s not use that as the standard we want to build on :). > Even if you could say that a timestamp is part of the logging domain it is not said if that timestamp needs to be part of the log object or the logger consuming this object. This question arises for every quality of a logging object. Even the logging level could be some behavioral quality that a logger matches to log levels. Contrary to this is logging thisContext which has to be done in the log object. > I think the hard part is the way of distribution of log objects and filtering of them. While the former is being discussed with Beacon the latter is mostly ignored while being really important. Not having default qualities of a log object is good on one hand but on the other hand the filtering is much harder. > In SystemLogger we didn't go far enough at first. The Log class contained level and such. That was the reason for me to split it into BasicLog consisting of timestamp and a message object and Log which contains the extra qualities. > > My problem with such approach is that it forces me to create hierarchy of log events as subclasses of base log component. But, you do not have to. Only if you want to distinguish between different log signals based on types. It is exactly the same type of problem that you have when you design the Exceptions in your system, or the domain-level Announcements in your system. Do you want to have fine grained types or use one single generic Exception? Do you want to have fine-grained or use plain Announcements? You can do it both ways, but it turns out you understand your system better if you use the types. Nevertheless, for prototyping purposes, you can certainly use quick logging. > Imaging that my application already provide hierarchy of events but they have no timestamps. How to log them? Should I use some WrapperSignal? > Now imaging that application uses some library which provides events too. But this events are log entries themselves. What I will see in my logs? > I will see mix of WrapperSignal's and normal events. It would be not easy to analize such log. > That's why I want unified log entries. I would model it with single class LogEntry which nobody needs to subclass. It would contain logging domain information: timestamp, importance level, user message and whatever. And it would have content property to keep logging object. So our tools can rely on this structure to make it easy to work with logs. And when anybody will look at particular log he will be sure that logging object is inside "content" variables of each record Signals are announcements. If you will have some events, those should be announcements. We could add to Announcements the ability to decorate an Announcement object (or at least a Signal one), we can tackle your scenario in a different way. Announcements is the unifying platform, not the logging. Logging is just an application of Announcements. But, the other point of view is that we should work to add instance variable filtering to Announcements, ideally in a way that does not pose performance penalty when you filter only by class. Once we do that we can have any combination you want. Also, just because you use Announcements does not put any limitation on the concrete domain objects you want to log. In any logging system you will have some wrapping object that will hold the concrete object. An Announcement is a great wrapping object exactly because it comes with the mechanism of transportation throughout the image, which is a technical prerequisite for logging anyway. Cheers, Doru -- www.tudorgirba.com www.feenk.com "Don't give to get. Just give." |
In reply to this post by Denis Kudriashov
Hi,
> On Apr 28, 2016, at 10:55 AM, Denis Kudriashov <[hidden email]> wrote: > > > 2016-04-28 10:20 GMT+02:00 Nicolai Hess <[hidden email]>: > What I am talking about is that I don't want create MySpecialLog for any MySpecialDomainObject which I want to log. > > Traits? > > Put you logging api in a Trait instead of Object and let your MySpecialDomainObject use this trait ? > > Really? > Try remember usual workflow when we investigate some problems with code when we can't use debugger. We put kind of "Transcript show:" in multiple places to see state of our objects at concrete point of time. With object logging we will log our objects directly without converting to strings. Do you want to stop your "debugging workflow" every time you need to log objects which not support it? (to add special trait). This is a totally different scenario than the one of logging for an unforeseen situation. For this purpose, in Beacon we have dedicated signals such as those that capture the stack or the context and we can imagine several more. It is more powerful than Transcript and requires no string. Furthermore, because we have the type signal, we can also easily have an inspector that shows the relevant information. > But anyway with Trait you can't add timestamp to your domain object which is always required for logs (I think we all agree about timestamp). We can indeed agree on timestamp, but as Sven said, we might need flexibility on how to capture it (DateAndTime vs ZTimestamp). Cheers, Doru -- www.tudorgirba.com www.feenk.com "What is more important: To be happy, or to make happy?" |
In reply to this post by stepharo
2016-04-27 21:11 GMT+02:00 stepharo <[hidden email]>: Denis I do not get what you mean with the sentence above. With SystemLogger we would write:
And your code will always create Log instance which would be useless garbage when nobody interested in it (not logs want it). Same with Beacon:
And especially it is problem when we log thisContext: It will always extract full stack information although not logs will record it. I think it is important to address this issue: logging code should be not expensive when nobody use logs. |
In reply to this post by stepharo
2016-04-27 21:12 GMT+02:00 stepharo <[hidden email]>:
But what about my example below?
Do you think it is not problem?
|
In reply to this post by Tudor Girba-2
2016-04-28 11:07 GMT+02:00 Tudor Girba <[hidden email]>: > Put you logging api in a Trait instead of Object and let your MySpecialDomainObject use this trait ? I hope you not think that I suggested to log strings. I never did it. I proposed to log domain objects instead of signals with ability to annotate them with additional information. |
In reply to this post by Tudor Girba-2
2016-04-28 11:07 GMT+02:00 Tudor Girba <[hidden email]>: But anyway with Trait you can't add timestamp to your domain object which is always required for logs (I think we all agree about timestamp). Domain objects can supply own timestamp to log entries. But both kinds of time should be polimorphic in some cases. By the way why we need multiple timestamp representation in system? Can we choose best option and use it anywhere? (But this question is not for this topic) |
Hi,
> On Apr 28, 2016, at 2:36 PM, Denis Kudriashov <[hidden email]> wrote: > > > 2016-04-28 11:07 GMT+02:00 Tudor Girba <[hidden email]>: > But anyway with Trait you can't add timestamp to your domain object which is always required for logs (I think we all agree about timestamp). > > We can indeed agree on timestamp, but as Sven said, we might need flexibility on how to capture it (DateAndTime vs ZTimestamp). > > Domain objects can supply own timestamp to log entries. I do not understand this point. Could you clarify? > But both kinds of time should be polimorphic in some cases. Certainly. > By the way why we need multiple timestamp representation in system? Can we choose best option and use it anywhere? (But this question is not for this topic) Indeed, we know that we do not need both, but someone has to clean them up :). In any case, in some cases you might want a certain precision even if it costs, and in others you do not. So, having the initialization of the timestamp factored out would be a good thing. Cheers, Doru -- www.tudorgirba.com www.feenk.com "Obvious things are difficult to teach." |
In reply to this post by Denis Kudriashov
Hi,
> On Apr 28, 2016, at 2:29 PM, Denis Kudriashov <[hidden email]> wrote: > > > 2016-04-28 11:07 GMT+02:00 Tudor Girba <[hidden email]>: > > Put you logging api in a Trait instead of Object and let your MySpecialDomainObject use this trait ? > > > > Really? > > Try remember usual workflow when we investigate some problems with code when we can't use debugger. We put kind of "Transcript show:" in multiple places to see state of our objects at concrete point of time. With object logging we will log our objects directly without converting to strings. Do you want to stop your "debugging workflow" every time you need to log objects which not support it? (to add special trait). > > This is a totally different scenario than the one of logging for an unforeseen situation. For this purpose, in Beacon we have dedicated signals such as those that capture the stack or the context and we can imagine several more. It is more powerful than Transcript and requires no string. Furthermore, because we have the type signal, we can also easily have an inspector that shows the relevant information. > > I hope you not think that I suggested to log strings. I never did it. I proposed to log domain objects instead of signals with ability to annotate them with additional information. No, I did not suggest that you want to log strings. I simply said that this type of use case is different than the regular logging use case. I think it is important to treat these two separately because indeed when you debug you are in a prototyping mode and you want to go fast. In this situation, you do not want to have to create a separate class. But, for the long term logging you have different requirements and there you want to be more rigorous, and in that scenario creating a new class is acceptable. If we design a logging infrastructure the second use case is what we want to optimize around. Of course, we should still think about the prototyping part. I found that it is often more interesting to log entire contexts (and have a post-mortem debugger) than individual objects. Nevertheless, with something as simple as: object asBeaconSignal log. It worked fine. And if I really wanted to add extra information, I rudimentary did: {‘some text’ . object } asBeaconSignal log. Or even: {‘some text’ . #someSymbol . 42 . object } asBeaconSignal log. It is not the most elegant solution, but it is very malleable and good enough for debugging purposes. If we would have instance-based filtering for announcements, we could filter based on that without any extra effort. Also, if we would have a composition mechanism in place, we could build these objects with a more elegant API. Regarding your statement of logging domain objects, you will have to store these objects with the additional information somewhere, and that will be a wrapper class. I do not see the difference with the Signal. Cheers, Doru -- www.tudorgirba.com www.feenk.com "We can create beautiful models in a vacuum. But, to get them effective we have to deal with the inconvenience of reality." |
In reply to this post by Tudor Girba-2
2016-04-28 14:42 GMT+02:00 Tudor Girba <[hidden email]>: > Domain objects can supply own timestamp to log entries. I think you mention something different than I had in mind. My case was when anObject already has internal timestamp it can pass it to log entry (signal) |
In reply to this post by Tudor Girba-2
2016-04-28 14:51 GMT+02:00 Tudor Girba <[hidden email]>:
And for such cases we definitely need simple #log message without #asBeaconSignal. It can be hidden inside. Or it can be:
|
In reply to this post by Tudor Girba-2
2016-04-28 14:51 GMT+02:00 Tudor Girba <[hidden email]>:
Instead domain objects will be added to logs inside general LogEntry instances which will be hidden from user and only available inside logs. And LogEntry will allow include additional information to itself by appropriate logging API. Question is: does it better? And this is what problem I see around Beacon: Beacon proposes to design log entries as events, as subclasses of BeaconSignal. If nothing else exists it is good. We will see in logs collection of such events. But what to do with existing domain events which has no relation to logs? How to log them if we decide to do it? They can be added to log inside WrapperSignal. But then we will see in logs mix of normal events which created specially for logs and WrapperSignal's containing original application events. But both type of events belong to same application. We definitely want to see them and to work with them in same way everywhere (especially inside logs) Tudor what do you think about this problem? Maybe I misunderstood Beacon. |
Hi Denis,
On Apr 28, 2016, at 4:43 PM, Denis Kudriashov <[hidden email]> wrote: Thanks for the dialogue. I think the most important part is to identify concerns and now we are getting concrete. So, let’s see :). Your LogEntry is exactly the same as BeaconSignal. There is no difference. You will also need to transport the LogEntry from your application to the logger object. Beacon reuses the Announcement framework to do just that. If you avoid the Announcement framework, you will implement another engine that has essentially the same responsibility. I think it is better to consolidate in this case. So, I see no downside of using Beacon for your purpose. But, I think there is more. One example where we have an event that is often worthwhile preserving is an Exception. In Beacon there is an out-of-the-box ExceptionSignal. This is not just a wrapper around the exception, but it also decides what to log from an Exception. For example, in order to ensure that we can have proper navigation of the exception, we capture the RB nodes for each stack entry. This is a naive implementation and we should certainly improve it (for example, we would need to delegate the computation of the stack information as late as possible), but it exemplifies how when you log you want to choose what to log. It can be that in another situation, we want to log the whole context of the exception. Furthermore, because we have a typed signal, we can also have a Stack presentation that depends on the strategy we used to log, not on the object that we logged. I believe this is a recurrent case. Nothing would prevent us from logging the exception through a plain WrapperSignal either. Only in that case we would not have the extra information that the ExceptionSignal provides. So, from this point of view, the ability to create types of signals is not a limitation, but an added value. That is why in my message I said that we should encourage people to create typed signals, but we should not enforce that. You mentioned that maybe your event object has a timestamp already. This timestamp is not the same as the logging timestamp, and it should be treated separately. If it is the same, that situation is so rare that I doubt we should optimize the whole framework around such a problem. Does this make sense? Cheers, Doru |
Hi Tudor. I think I super bad in explaining things because you not answer my question. As you said we should encourage people to create typed signals. I am not against it. But I try to explain that approach of Beacon is wrong. It is wrong to make this signals be subclasses of Beacon core component BeaconSignal. We have in Pharo 307 subclasses of Announcements (only 78 have some kind of time variable). Do not they all are signals for logging? But only way how to log them in Beacon is to wrap them by kink of WrapperSignal. Does my issue is clear now? At the end we will got logs with mix of normal events which created specially for logs and WrapperSignal's containing original application events. 2016-04-28 23:39 GMT+02:00 Tudor Girba <[hidden email]>:
|
In reply to this post by Denis Kudriashov
Le 28/4/16 à 10:13, Denis Kudriashov a
écrit :
I do not get it. Inheritance is good and if you combine it with delegation you can rule part of the world. BasicLog timeStamp object: MySpecialLog what I want |
In reply to this post by Tudor Girba-2
> No, I did not suggest that you want to log strings. I simply said that this type of use case is different than the regular logging use case. I think it is important to treat these two separately because indeed when you debug you are in a prototyping mode and you want to go fast. In this situation, you do not want to have to create a separate class. But, for the long term logging you have different requirements and there you want to be more rigorous, and in that scenario creating a new class is acceptable. If we design a logging infrastructure the second use case is what we want to optimize around. Indeed Logging is not just about replace Transcript show: > > Of course, we should still think about the prototyping part. I found that it is often more interesting to log entire contexts (and have a post-mortem debugger) than individual objects. Nevertheless, with something as simple as: > > object asBeaconSignal log. > > It worked fine. > > And if I really wanted to add extra information, I rudimentary did: > > {‘some text’ . object } asBeaconSignal log. > > Or even: > > {‘some text’ . #someSymbol . 42 . object } asBeaconSignal log. I got a similar but not based on array but with a block to handle extension without subclasses. > > It is not the most elegant solution, but it is very malleable and good enough for debugging purposes. If we would have instance-based filtering for announcements, we could filter based on that without any extra effort. Also, if we would have a composition mechanism in place, we could build these objects with a more elegant API. > > Regarding your statement of logging domain objects, you will have to store these objects with the additional information somewhere, and that will be a wrapper class. I do not see the difference with the Signal. > > Cheers, > Doru > > -- > www.tudorgirba.com > www.feenk.com > > "We can create beautiful models in a vacuum. > But, to get them effective we have to deal with the inconvenience of reality." > > > |
In reply to this post by Denis Kudriashov
Le 28/4/16 à 15:06, Denis Kudriashov a
écrit :
Yes I would prefer that instead sending add: Log information: {‘some text’ . #someSymbol . 42 . object } |
Free forum by Nabble | Edit this page |