Hi all,
I am currently 'porting' (redoing) the OpenBSC/Osmocom logging framework in Smalltalk and while developing I see that I have one question/issue with updating the code. I have a LogArea which is a three tuple of (description, enabled, minLevel), I have a LogConfig that holds a list of areas and gives them local names. So I have something like: Object subclass: LogConfig [ Config := LogConfig new. LogConfig class >> default [ ^ Config ] addArea: anArea name: aName [ addInstanceVariableAndSetIt GenerateGetMethod... ] ] and in another Package/Namespace I would do.. log.LogConfig defaut addArea: localArea: #localName.. Now I have two issues: 1.) 1 to 3: [SomeClass class addInstVarName: #boo], will add #boo three. Is that a bug? That should not be possible, bad things will happen as a result.. 2.) FileStream fileIn: 'Log.st'. will set Config back to a new instance of LogConfig and all added areas are gone. What are the workarounds? Put Config into the Smalltalk dict? Use Notifications so people can add their areas again? thanks for the help z. PS: I looked at Logging on squeaksource but I will need more.. different areas, min debug level per area, context... e.g. only debug if this process is handling data for this IMSI _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On Mon, Sep 6, 2010 at 09:11, Holger Hans Peter Freyther
<[hidden email]> wrote: > Hi all, > > I am currently 'porting' (redoing) the OpenBSC/Osmocom logging framework in > Smalltalk and while developing I see that I have one question/issue with > updating the code. > > I have a LogArea which is a three tuple of (description, enabled, minLevel), I > have a LogConfig that holds a list of areas and gives them local names. > > So I have something like: > > Object subclass: LogConfig [ > Config := LogConfig new. > > LogConfig class >> default [ > ^ Config > ] > > addArea: anArea name: aName [ > addInstanceVariableAndSetIt > GenerateGetMethod... > ] > ] > > and in another Package/Namespace I would do.. > > log.LogConfig defaut addArea: localArea: #localName.. Passing note: namespaces are usually capitalized. > Now I have two issues: > 1.) 1 to 3: [SomeClass class addInstVarName: #boo], will add #boo > three. Is that a bug? That should not be possible, bad things > will happen as a result.. It's a bit ugly, but not strictly a bug. I suggest you use a dictionary, and #doesNotUnderstand: instead of a getter, especially because you're adding the instance variables to _all_ instances of LogConfig rather than just one. > 2.) FileStream fileIn: 'Log.st'. will set Config back to a new > instance of LogConfig and all added areas are gone. What are the > workarounds? Put Config into the Smalltalk dict? Use Notifications > so people can add their areas again? This would be fixed by using a dictionary and #doesNotUnderstand:, too. Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 09/06/2010 04:30 PM, Paolo Bonzini wrote:
> > It's a bit ugly, but not strictly a bug. I suggest you use a > dictionary, and #doesNotUnderstand: instead of a getter, especially > because you're adding the instance variables to _all_ instances of > LogConfig rather than just one. Two more questions 1.) is it possible to only add instance variables only to one instance? How would I do it? '123' addInstVarNamed didn't work here. 2.) #doesNotUnderstand will not work from what I see as the Logging Module does not know who is going to add areas to it, unless I do something like LogConfig allSubClassesDo: []... is that appropriate? _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 09/06/2010 11:46 AM, Holger Hans Peter Freyther wrote:
> On 09/06/2010 04:30 PM, Paolo Bonzini wrote: >> It's a bit ugly, but not strictly a bug. I suggest you use a >> dictionary, and #doesNotUnderstand: instead of a getter, especially >> because you're adding the instance variables to _all_ instances of >> LogConfig rather than just one. > > Two more questions > > 1.) is it possible to only add instance variables only to one instance? How > would I do it? '123' addInstVarNamed didn't work here. You need to create a "lightweight class", like | cl | cl := Behavior new. cl superclass: instance class. instance changeClassTo: cl. cl addInstVarNamed: 'a'. However, it's broken and only works if "instance class" has no instance variables at all. I'll shortly push a fix. > 2.) #doesNotUnderstand will not work from what I see as the Logging Module > does not know who is going to add areas to it, unless I do something like > LogConfig allSubClassesDo: []... is that appropriate? I don't understand why would you subclass LogConfig rather than create multiple instances? Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 09/06/2010 06:24 PM, Paolo Bonzini wrote:
> However, it's broken and only works if "instance class" has no instance > variables at all. I'll shortly push a fix. awesome! GNU Smalltalk is getting better and better, does anyone think a windows version will help us to get more devs? > >> 2.) #doesNotUnderstand will not work from what I see as the Logging Module >> does not know who is going to add areas to it, unless I do something like >> LogConfig allSubClassesDo: []... is that appropriate? > > I don't understand why would you subclass LogConfig rather than create > multiple instances? Maybe my approach is wrong, so let me recap. I have multiple subsystems that add their own areas but I want to write code like this anObject logDebug: 'message' area: #sccp. So for this I need to have a LogConfig per Process (or one global one to start with). _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On Mon, Sep 6, 2010 at 12:53, Holger Hans Peter Freyther
<[hidden email]> wrote: >>> 2.) #doesNotUnderstand will not work from what I see as the Logging Module >>> does not know who is going to add areas to it, unless I do something like >>> LogConfig allSubClassesDo: []... is that appropriate? >> >> I don't understand why would you subclass LogConfig rather than create >> multiple instances? > > Maybe my approach is wrong, so let me recap. I have multiple subsystems that > add their own areas but I want to write code like this anObject logDebug: > 'message' area: #sccp. So for this I need to have a LogConfig per Process (or > one global one to start with). Do you have a pointer to the API you're taking inspiration from? Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 09/06/2010 07:09 PM, Paolo Bonzini wrote:
> > Do you have a pointer to the API you're taking inspiration from? Header File: http://git.osmocom.org/gitweb?p=libosmocore.git;a=blob;f=include/osmocore/logging.h;h=7f33155a8330d5bc59d0262140ed3e8fea34050a;hb=HEAD Implementation: http://git.osmocom.org/gitweb?p=libosmocore.git;a=blob;f=src/logging.c;h=5be4e58ed485837dca221a6f0f3f48387e7620ca;hb=HEAD Config/Setup: http://openbsc.osmocom.org/trac/browser/openbsc/src/bsc_hack.c#L223 (create a target to log to stderr, initialize the area used by the app, allow everything to pass the filter) Filter/Context setup: http://openbsc.osmocom.org/trac/browser/openbsc/src/abis_rsl.c#L125 The framework is working good in OpenBSC. With the different targets we can enable to log to our telnet interface (VTY from quagga), but only log messages related to a specific subscriber (e.g. doing call testing and only want to see my own messages). _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On Tue, Sep 7, 2010 at 03:45, Holger Hans Peter Freyther
<[hidden email]> wrote: > Header File: > http://git.osmocom.org/gitweb?p=libosmocore.git;a=blob;f=include/osmocore/logging.h;h=7f33155a8330d5bc59d0262140ed3e8fea34050a;hb=HEAD Ok, so... 73 struct log_target { 74 struct llist_head entry; 75 76 int filter_map; 77 void *filter_data[LOG_MAX_FILTERS+1]; 78 79 struct log_category categories[LOG_MAX_CATEGORY+1]; 80 uint8_t loglevel; 81 int use_color:1; 82 int print_timestamp:1; 83 84 union { 85 struct { 86 FILE *out; 87 const char *fname; 88 } tgt_file; 89 90 struct { 91 int priority; 92 } tgt_syslog; 93 94 struct { 95 void *vty; 96 } tgt_vty; 97 }; 98 99 void (*output) (struct log_target *target, const char *string); 100 }; I would not be too fussy about reproducing the exact characteristics of the API. I guess subsys is what you called "area". The basic hierarchy here is LogEntry (simple struct: subsys/level/context replacing file+line/string) LogTarget (methods create LogEntry and pass it to an abstract method) LogFilter (see below) LogFile (better: LogStream?) LogSyslog LogFilters wrap another LogTarget and only pass through items in a select category. You can have class methods to create commonly used filters, or you can make a subhierarchy like LogFilter (abstract) LogAreaFilter (enable one area or disable one area) LogEnableAreaFilter LogDisableAreaFilter LogLogicFilter LogAndFilter LogOrFilter LogNotFilter LogLevelFilter LogPluggableFilter but that can come later. LogTarget class methods can be used to set a default logging target and, as you mentioned, you could have also a per-process LogTarget. You can add a LogMultiplexer class to emulate log_add_target/log_del_target. It can be just an internal detail. How does this look? Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 09/07/2010 04:23 PM, Paolo Bonzini wrote:
> LogTarget class methods can be used to set a default logging target > and, as you mentioned, you could have also a per-process LogTarget. > > You can add a LogMultiplexer class to emulate > log_add_target/log_del_target. It can be just an internal detail. > > How does this look? Thanks for taking the time, the LogFilter hierachy is a nice idea. One reason to have the dedicated 'LogArea' class is from a configuration point of view. A user does not want to reconfigure the LogTarget (and the filters applied on it) but he wants to see the SCCP messages. So currently on the telnet interface I do something like: logging SCCP enabled. With the filtering I would have to add an allow filter, or remove from the target which is certainly possible but a bit of a hassle. On the other hand by having a nice chain of filters one can do a lot more. _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 09/07/2010 10:53 AM, Holger Hans Peter Freyther wrote:
> On 09/07/2010 04:23 PM, Paolo Bonzini wrote: > > >> LogTarget class methods can be used to set a default logging target >> and, as you mentioned, you could have also a per-process LogTarget. >> >> You can add a LogMultiplexer class to emulate >> log_add_target/log_del_target. It can be just an internal detail. >> >> How does this look? > > Thanks for taking the time, the LogFilter hierachy is a nice idea. One reason > to have the dedicated 'LogArea' class is from a configuration point of view. > > A user does not want to reconfigure the LogTarget (and the filters applied on > it) but he wants to see the SCCP messages. So currently on the telnet > interface I do something like: > > logging SCCP enabled. > > With the filtering I would have to add an allow filter, or remove from the > target which is certainly possible but a bit of a hassle. On the other hand by > having a nice chain of filters one can do a lot more. Yeah, maybe the LogFilter hierarchy sacrifices usability too much. It's nice to be able to modify the filter. Maybe you can make instead a hierarchy with LogFilter on the side instead of under LogTarget: LogEntry LogPolicy (abstract) LogFilter (implements a dynamically-changeable filter) LogTarget LogFile LogSyslog LogMultiplexer Then every LogTarget has a LogPolicy and you can send messages like LogTarget>>policy ^policy ifNil: [policy := self defaultPolicy] LogTarget>>defaultPolicy ^LogFilter new minimumLevel: LogEntry error; yourself LogTarget default policy disable: #SCCP. LogTarget processDefault policy enable: #SCCP minimumLevel: LogEntry all. Then LogTarget's logging method would have to create LogEntry, test it against its LogFilter, and if successful pass it to the abstract method. Another idea: LogPolicies could make a chain and, if the object specifies neither enable nor disable, it could delegate to the next policy. So for example the process-default policy could delegate to the global policy. This delegation could be implemented in the abstract class. LogPolicy>>accept: anEntry (self shouldAccept: anEntry) ifTrue: [^true]. (self shouldRejept: anEntry) ifTrue: [^false]. ^self next isNil ifTrue: [true] ifFalse: [self next accept: anEntry] LogPolicy>>shouldAccept: anEntry self subclassResponsibility LogPolicy>>shouldReject: anEntry self subclassResponsibility LogTarget>>defaultPolicy | policy | policy := LogFilter new minimumLevel: LogEntry error; yourself. self == self class default ifFalse: [policy next: self class default policy]. ^policy (BTW, LogMultiplexer can have its own policy, which is combined (logically by an AND) with its targets' policies). Does this look nicer? Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |