diff --git a/ChangeLog b/ChangeLog index bd9d169..dc291dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ * EcCommand.m: Simplify handling of loss of process and configuration error alarms. Clear such alarms when we receive a ping from the process. + EcLogger.[hm]: Add documentation in the header, plus a new method to + make subclassing a bit easier. Fix bug in naming of config keys. 2014-09-04 Richard Frith-Macdonald diff --git a/EcLogger.h b/EcLogger.h index 0ad8606..2b63a07 100644 --- a/EcLogger.h +++ b/EcLogger.h @@ -30,6 +30,24 @@ #ifndef _ECLOGGER_H #define _ECLOGGER_H +/** Instances of the EcLogger class are used to handle various types of + * logging.
+ * The default implementation supports writing to local files and sending + * logs to a remote process (by default, the Command server).
+ * Configuration options control the amount of data buffered in memory + * before logs are flushed, and the amount of time for which data may + * be buffered in memory before being flushed.
+ * Configuration options are ???Server (to specify the name of the + * server to log to if not Command) and ???Flush (to specify when to + * flush the in-memory buffer), where ??? is the type of logging being + * done by a logger object.
+ * When there is no type-specific flush configuration, the DefaultFlush + * configuration key will be used.
+ * The flush configuration value must be a floating point number of + * seconds after which to flush, optionally folowed by a colon and an + * integer number of kilobytes of data allowed before the buffer is + * flushed. + */ @interface EcLogger : NSObject { NSRecursiveLock *lock; @@ -48,17 +66,50 @@ BOOL registered; BOOL pendingFlush; } + +/** Returns a (cached) logger object for the specified type of logging.
+ * Creates a new object (adding it to the cache) if none exists. + */ + (EcLogger*) loggerForType: (EcLogType)t; + +/** Sets the factory class used by the +loggerForType: method + * to create new EcLogger objects.
+ * This is provided as a convenience so that you can get all code to use + * a subclass of EcLogger without having to use a category to override + * that method. + */ ++ (void) setFactory: (Class)c; + +/** Supports the CmdPing protocol. + */ - (void) cmdGnip: (id )from sequence: (unsigned)num extra: (NSData*)data; + - (void) cmdMadeConnectionToServer: (NSString*)name; + +/** Supports the CmdPing protocol. + */ - (void) cmdPing: (id )from sequence: (unsigned)num extra: (NSData*)data; + +/** Called to flush accumulated data from the message instance variable.
+ * On return from this method the variable should be empty. + */ - (void) flush; + +/** Called to log a message by appending to the message instance variable. + * This method may also schedule an asynchronous flush if the message + * buffer is too large or if the last flush was too long ago. + */ - (void) log: (NSString*)fmt arguments: (va_list)args; + +/** Called when the user defaults system has changed and a configuration + * update may have occurred. + */ - (void) update; + @end #endif diff --git a/EcLogger.m b/EcLogger.m index e3a54cf..cf6d350 100644 --- a/EcLogger.m +++ b/EcLogger.m @@ -35,6 +35,7 @@ @implementation EcLogger +static Class loggersClass; static NSLock *loggersLock; static NSMutableArray *loggers; static NSArray *modes; @@ -49,6 +50,7 @@ static NSArray *modes; loggers = [[NSMutableArray alloc] initWithCapacity: 6]; objects[0] = NSDefaultRunLoopMode; modes = [[NSArray alloc] initWithObjects: objects count: 1]; + [self setFactory: self]; } } @@ -69,16 +71,16 @@ static NSArray *modes; return logger; } } - logger = [[EcLogger alloc] init]; + logger = [[loggersClass alloc] init]; if (logger != nil) { logger->lock = [NSRecursiveLock new]; logger->type = t; logger->key = [cmdLogKey(t) copy]; logger->flushKey - = [[NSString alloc] initWithFormat: @"BS%@Flush", logger->key]; + = [[NSString alloc] initWithFormat: @"%@Flush", logger->key]; logger->serverKey - = [[NSString alloc] initWithFormat: @"BS%@Server", logger->key]; + = [[NSString alloc] initWithFormat: @"%@Server", logger->key]; logger->interval = 10.0; logger->size = 8 * 1024; logger->message = [[NSMutableString alloc] initWithCapacity: 2048]; @@ -96,6 +98,15 @@ static NSArray *modes; return logger; } ++ (void) setFactory: (Class)c +{ + if (Nil == c) c = [self class]; + NSAssert([c isSubclassOfClass: self], NSInvalidArgumentException); + [loggersLock lock]; + loggersClass = c; + [loggersLock unlock]; +} + /* Should only be called on main thread, but doesn't matter. */ - (void) cmdGnip: (id )from @@ -530,7 +541,7 @@ static NSArray *modes; str = [defs stringForKey: flushKey]; if (str == nil) { - str = [defs stringForKey: @"BSDefaultFlush"]; // Default settings. + str = [defs stringForKey: @"DefaultFlush"]; // Default settings. } if (str != nil) {