Hi,


On Wed, Jun 18, 2014 at 1:38 PM, Norbert Hartl <norbert@hartl.name> wrote:

Am 18.06.2014 um 12:39 schrieb Tudor Girba <tudor@tudorgirba.com>:

Hi Sven,

Thanks for pushing this.

For Beacon, you do not need the wrapper because that is meant for other objects that are not announcements. If you use the Wrapper you lose the type of the event. So, the integration can be even simpler and more powerful:
ZnLogEvent announcer
�� �� �� �� when: ZnLogEvent
�� �� �� �� do: [ :each | each log ]
�� �� �� �� for: #beacon.

Afterwards, we can listen to specific events only by using the Announcement filtering mechanism.

Taking a step back, indeed it is easy to write the code to integrate but it comes at the cost of indirection. Specifically for logging we want the overhead to be as cheap as possible, and for this reason, we want the integration to be as tight as possible.

If we look at it, all these three solutions have identical structure:
- there is an event (Log, Announcement)
- there is something like a broker through which the events are being triggered (LogDispatcher, Beacon,��ZnLogEvent announcer)
- there are bindings that do something concrete with the events (Logger, BoundedBeacon, AnnouncementSpy)

In the case of using Announcements, we can just have support for a central announcer in the image and the integration would be even tighter. For example, if ZnLogEvent would use this global announcer, rather than its own global announcer, it would be cheaper.

Cheaper in which aspect? Did you test? If you have one central announcer that has 10 listeners attached what is cheaper than? Every subscription has to be tested for every event. Listening to you and Sven I got the idea that localized announcers could be better. I could compose the announcers I���m interested in into a central composer and ignore stuff I���m not interested in. It���s about tradeoffs.

Having to send the same announcement twice is certainly worse than sending it only once :).

I completely agree that allowing for cheap localized announcers is the way to go. The central one is just a convenience so that I can write "Signal log", nothing more. This is exactly the reason why I argue that going the route of announcers is better because we will have more and more of them, and we will benefit from all the analysis tooling that we can build on top for many different use cases.
��
So, I think the main thing is just to agree on the transmission mechanism. As we have Announcements already, the question is why implement another one? Or, if it is a nail, perhaps a hammer is the right thing to use :)

The transmission mechanism ist the only thing we are talking about. If you install an central announcer it isn���t much different to the LogDispatcher.

That is what I try to show in the list above (in the parentheses I listed the corresponding concepts in the various implementations). All approaches have the same structure. We are just talking about the transmission :).

��
So this is a lot of discussion for a single aspect.

This is not a secondary one. As I said, you will get more and more announcers and announcements. We can capitalize on that beautifully. For example, Sven used the AnnouncementSpy for his use case without any cost. This shows that the concepts are the same and we should capitalize on that.
��

I think supporting popular use cases is even more important. I still had no time to look at all the code but I would be interested how real use cases are done with your approach.��

I would be interested in a list of what people consider popular use cases as well.

��
I have one LogDispatcher with to Loggers: one syslog logger and one custom logger. The syslog logger events need a log level and a tag assigned.

I consider that level and tags are not needed.

��
The custom logger takes events converts them to json and transmits them to another image via http.

Great. We certainly need this kind of effort. Can you point me to this code so that I can try to implement it in Beacon to see how it looks like?

��
So I guess the main difficulty lays in the distribution and filtering of events and not only in the best way to get it out of the own code.

I agree that it is challenging and that we need work there, but I would not dismiss the basics :).


Doru

��
Norbert

����
Cheers,
Doru



On Wed, Jun 18, 2014 at 11:15 AM, Sven Van Caekenberghe <sven@stfx.eu> wrote:
Hi,

I think we are all pretty much on the same page with how we think logging has to be done. In any case, here is the code (one, 1, line of code) that connects ZnLogEvent with either SystemLogger or Beacon - provided I understood everything correctly.

ZnLogEvent announcer
�� �� �� �� when: ZnLogEvent
�� �� �� �� do: [ :each | BasicLog message: each ]
�� �� �� �� for: #systemLogger.

ZnLogEvent announcer
�� �� �� �� when: ZnLogEvent
�� �� �� �� do: [ :each | WrapperSignal log: each ]
�� �� �� �� for: #beacon.

Now this is using a wrapper object, BasicLog and WrapperSignal respectively. It even seems to work without the wrapping as well.

ZnLogEvent announcer
�� �� �� �� when: ZnLogEvent
�� �� �� �� do: [ :each | LogDispatcher current addLog: each ]
�� �� �� �� for: #systemLogger.

ZnLogEvent announcer
�� �� �� �� when: ZnLogEvent
�� �� �� �� do: [ :each | Beacon announce: each ]
�� �� �� �� for: #beacon.

Question is, is the wrapping needed ? For the implementation or for the user ? Right now, only a timestamp is added. As I indicated before, I don't think that even 'forcing' a particular timestamp is a good idea. Here is my reasoning.

Log events arrive in a certain order and that order should be maintained. Making log events sortable could be nice to have, but it is not 100% necessary. The same goes for uniquely identifying log events, nice to have but not necessary.

A timestamp might seem like a good idea for both properties, but it is not. Consider:

(Array streamContents: [ :set | 1000 timesRepeat: [ set nextPut: DateAndTime now ] ]) asSet.

The set will contain only a couple of instances. And this is for the most precise timing that we currently have. It is also easy to think of alternatives for DateAndTime that some people might prefer: just Time, seconds, micro or milliseconds since a reference, ZTimestamp (which I use in other code), some class from Chronos, whatever. Features, abstraction, performance, precision, memory consumption are all different.

But regardless of clock precision, I think an id is useful as a secondary sort or identity criterium, just in case. But again, I would not require it.

On the other hand, we need common protocol. What about the following: each log event object should implement #timestamp, which has to return a Magnitude compatible object so that increasing values conform with the order of the events (but not necessarily vice versa).

Sven






--

"Every thing has its own flow"




--
www.tudorgirba.com

"Every thing has its own flow"