mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-16 00:21:01 +00:00
move documentation and add new method for creating/adding an alerter event
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/ec/trunk@36448 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
ba9a2d9275
commit
5b902f7567
2 changed files with 443 additions and 386 deletions
195
EcAlerter.h
195
EcAlerter.h
|
@ -37,6 +37,122 @@
|
|||
@class NSTimer;
|
||||
|
||||
|
||||
/**
|
||||
* <p>This class handles delivery and logging of error and alert messages
|
||||
* to the people who should be monitoring the system. It is used by the
|
||||
* Control server (to which all these messages are delivered) and
|
||||
* implements a simple rule based mechanism for managing final
|
||||
* delivery of the messages.
|
||||
* </p>
|
||||
* <p>The configured rules are compared against each message and any
|
||||
* actions associated with a matching rule are performed.<br />
|
||||
* The matching fields in each rule are -
|
||||
* </p>
|
||||
* <deflist>
|
||||
* <term>Host</term>
|
||||
* <desc>An extended regular expression to match the name of the host
|
||||
* machine on which the message originated (possibly just the host name).
|
||||
* If this is not specified, messages from any host may match.
|
||||
* </desc>
|
||||
* <term>Server</term>
|
||||
* <desc>An extended regular expression to match the name of the server
|
||||
* process from which the message originated (possibly just the server
|
||||
* name).
|
||||
* If this is not specified, messages from any server may match.
|
||||
* </desc>
|
||||
* <term>Type</term>
|
||||
* <desc>The type of message ... <em>Error</em> or <em>Alert</em>.
|
||||
* If this is not specified, messages of any type may match.
|
||||
* </desc>
|
||||
* <term>Pattern</term>
|
||||
* <desc>An extended regular expression used to match the main text
|
||||
* of the message. See the posix regcomp documentation for details
|
||||
* of enhanced posix regular expressions. If this is not present,
|
||||
* any message text will match.
|
||||
* </desc>
|
||||
* <term>Stop</term>
|
||||
* <desc>A boolean (YES or NO) saying whether rule matching should
|
||||
* stop if this rule is matched. If this is NO (the default) then
|
||||
* after any action associated with this rule is performed, matching
|
||||
* continues at the next rule.<br />
|
||||
* <em>Don't use this option injudiciusly. Try to write your pattern
|
||||
* matching rules so that most messages match a single rule to map
|
||||
* them to a nice readable version, and also match a default rule to
|
||||
* log full details to the technical team.</em>
|
||||
* </desc>
|
||||
* <term>Flush</term>
|
||||
* <desc>A boolean (YES or NO) saying whether stored messages due to
|
||||
* be sent out later should be sent out immediately after processing
|
||||
* this rule. This is useful in the event that some time critical
|
||||
* message must be sent, but should not normally be used.<br />
|
||||
* As a special case, instead of the boolean value, this may take
|
||||
* the value <em>Email</em> or <em>Sms</em> indicating that a flush
|
||||
* should be performed, but only on the specified type of messages.<br />
|
||||
* <strong>beware</strong> The batching mechanism exists to prevent
|
||||
* a single problem triggering floods of messages. You should only
|
||||
* override it using <em>Flush</em> where you are <strong>sure</strong>
|
||||
* that messages triggering the flush will be infrequent.
|
||||
* </desc>
|
||||
* </deflist>
|
||||
* <p>There are two additional fields <em>Extra1</em> and <em>Extra2</em>
|
||||
* which are matched against the message. These patterns do not effect
|
||||
* whether the action of the rule is executed or not, but the text matched
|
||||
* is made available for substitution into replacement messages.
|
||||
* </p>
|
||||
* <p>When a match is found the full message is normally sent to all the
|
||||
* destinations listed in the <em>Email</em> and <em>Sms</em> arrays in
|
||||
* the rule, and logged to all the destinations in the <em>Log</em> array.<br />
|
||||
* However, the <em>Replacement</em> field may be used to specify
|
||||
* a message to be sent in the place of the one received. Within the
|
||||
* <em>Replacement</em> string values enclosed in curly brackets will
|
||||
* be substituted as follows -
|
||||
* </p>
|
||||
* <deflist>
|
||||
* <term>Extra1</term>
|
||||
* <desc>The text in the message matched by the Extra1 pattern (if any)</desc>
|
||||
* <term>Extra2</term>
|
||||
* <desc>The text in the message matched by the Extra2 pattern (if any)</desc>
|
||||
* <term>Host</term>
|
||||
* <desc>The host name of the original message</desc>
|
||||
* <term>Server</term>
|
||||
* <desc>The server name of the original message</desc>
|
||||
* <term>Type</term>
|
||||
* <desc>The type of the original message</desc>
|
||||
* <term>Timestamp</term>
|
||||
* <desc>The timestamp of the original message</desc>
|
||||
* <term>Message</term>
|
||||
* <desc>The text of the original message</desc>
|
||||
* <term>Match</term>
|
||||
* <desc>The text matched by the <em>Pattern</em> if any</desc>
|
||||
* </deflist>
|
||||
* <p>The <em>Log</em> array specifies a list of log destinations which are
|
||||
* normally treated as filenames (stored in the standard log directory).
|
||||
* However, a value beginning 'database:' * is logged to a
|
||||
* database (the default database configured for SQLClient).<br />
|
||||
* After the colon you may place a table name, but if you don't then
|
||||
* the message will be logged to the 'Alert' table.<br />
|
||||
* The values logged in separate fields are the Timestamp, Type, Server, Host,
|
||||
* Extra1, Extra2, and full log text (as produced by the Replacement config)
|
||||
* is written into the Message field of the table after having been truncated
|
||||
* to 200 chars. Because of the truncation limit, it is recommended that
|
||||
* if you are trying to include the original alert {Message} (rather
|
||||
* than rewriting it) the Replacement does not include Timestamp,
|
||||
* Type, Server, Host, Extra1, Extra2 which are already saved in
|
||||
* separate fields, and would take up a lot of the 200 chars, which would
|
||||
* be better used to log the actual message.
|
||||
*
|
||||
* </p>
|
||||
* <p>The <em>Sms</em> array lists phone numbers to which Sms alerts are
|
||||
* to be sent.
|
||||
* </p>
|
||||
* <p>The <em>Email</em> array lists email addresses to which email alerts are
|
||||
* to be sent.<br />
|
||||
* An optional 'Subject' field may be present in the rule ... this is used
|
||||
* to specify that the is to be tagged with the given subject line. This
|
||||
* <em>defeats</em> batching of messages in that only messages with the
|
||||
* same subject may be batched in the same email.
|
||||
* </p>
|
||||
*/
|
||||
@interface EcAlerter : NSObject
|
||||
{
|
||||
NSArray *rules;
|
||||
|
@ -48,15 +164,88 @@
|
|||
NSString *ePort;
|
||||
GSMimeSMTPClient *smtp;
|
||||
}
|
||||
|
||||
/** Called when user defaults are updated, this fetches the dictionary
|
||||
* 'Alerter' from the defaults system, and passes it to the
|
||||
* -configureWithDefaults: method.
|
||||
*/
|
||||
- (BOOL) configure: (NSNotification*)n;
|
||||
|
||||
/** Called to set up or modify the configuration of the alerter.<br />
|
||||
* The dictionary c must contain (keyed on <code>Rules</code> an
|
||||
* array of dictionaries, each of which provides a rule for
|
||||
* delivering some form of alert.<br />
|
||||
* Other values in the configuration are used for standard configuration
|
||||
* of message delivery to the queueing system etc.
|
||||
*/
|
||||
- (BOOL) configureWithDefaults: (NSDictionary*)c;
|
||||
- (void) handleInfo: (NSString*)str;
|
||||
|
||||
/** This method is called to flush any batched email messages.
|
||||
*/
|
||||
- (void) flushEmail;
|
||||
|
||||
/** This method is called to flush any batched SMS messages.
|
||||
*/
|
||||
- (void) flushSms;
|
||||
|
||||
/** <p>This method handles an error/alert event (an 'error' is one which may
|
||||
* be buffered, while an 'alert' must be sent immediately).
|
||||
* </p>
|
||||
* <p>Each event must consist of text associated with a host anme,
|
||||
* server name (usually the process on the host) and timestamp.
|
||||
* </p>
|
||||
* <p>Each message is matched against each rule in the <em>Rules</em>
|
||||
* configuration in turn, and the first match found is used. The
|
||||
* message is sent to the people listed in the <code>Email</code> and
|
||||
* <code>Sms</code> entries in the rule (which may be either single
|
||||
* names or arrays of names).
|
||||
* </p>
|
||||
*/
|
||||
- (void) handleEvent: (NSString*)text
|
||||
withHost: (NSString*)hostName
|
||||
andServer: (NSString*)serverName
|
||||
timestamp: (NSString*)timestamp
|
||||
immediate: (BOOL)immediate;
|
||||
|
||||
/** <p>This method handles error/alert messages. It is able to handle
|
||||
* multiple (newline separated messages.
|
||||
* </p>
|
||||
* <p>Each message must be a line of the format -<br />
|
||||
* serverName(hostName): YYYY-MM-DD hh:mm:ss.mmm szzzz type - text
|
||||
* </p>
|
||||
* <p>Each message is parsed an then the components are passed to
|
||||
* the -handleEvent:withHost:andServer:timestamp:immediate: method.
|
||||
* </p>
|
||||
*/
|
||||
- (void) handleInfo: (NSString*)str;
|
||||
|
||||
/** Called by -handleEvent:withHost:andServer:timestamp:immediate:
|
||||
* to log a message to an array of destinations.
|
||||
*/
|
||||
- (void) log: (NSMutableDictionary*)m to: (NSArray*)destinations;
|
||||
|
||||
/** Called by -handleEvent:withHost:andServer:timestamp:immediate:
|
||||
* to pass a message to an array of destinations.
|
||||
* The message is actually appended to any cached messages for those
|
||||
* destinations ... and the cache is periodically flushed.
|
||||
*/
|
||||
- (void) mail: (NSMutableDictionary*)m to: (NSArray*)destinations;
|
||||
- (void) sms: (NSMutableDictionary*)m to: (NSArray*)destinations;
|
||||
- (void) timeout: (NSTimer*)t;
|
||||
|
||||
/** Cache a copy of the Rules with modifications to store information
|
||||
* so we don't need to regenerate it every time we check a message.
|
||||
*/
|
||||
- (BOOL) setRules: (NSArray*)ra;
|
||||
|
||||
/** Called by -handleEvent:withHost:andServer:timestamp:immediate:
|
||||
* to pass a message to an array of destinations.
|
||||
* The message replaces any cached messages for those
|
||||
* destinations (and has a count of the lost messages noted) ... and
|
||||
* the cache is periodically flushed.
|
||||
*/
|
||||
- (void) sms: (NSMutableDictionary*)m to: (NSArray*)destinations;
|
||||
|
||||
/** Responsible for the periodic calling of -flushEmail and -flushSms
|
||||
*/
|
||||
- (void) timeout: (NSTimer*)t;
|
||||
@end
|
||||
|
||||
|
|
634
EcAlerter.m
634
EcAlerter.m
|
@ -122,132 +122,8 @@ replaceFields(NSDictionary *fields)
|
|||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This class handles delivery and logging of error and alert messages
|
||||
* to the people who should be monitoring the system. It is used by the
|
||||
* Control server (to which all these messages are delivered) and
|
||||
* implements a simple rule based mechanism for managing final
|
||||
* delivery of the messages.
|
||||
* </p>
|
||||
* <p>The configured rules are compared against each message and any
|
||||
* actions associated with a matching rule are performed.<br />
|
||||
* The matching fields in each rule are -
|
||||
* </p>
|
||||
* <deflist>
|
||||
* <term>Host</term>
|
||||
* <desc>An extended regular expression to match the name of the host
|
||||
* machine on which the message originated (possibly just the host name).
|
||||
* If this is not specified, messages from any host may match.
|
||||
* </desc>
|
||||
* <term>Server</term>
|
||||
* <desc>An extended regular expression to match the name of the server
|
||||
* process from which the message originated (possibly just the server
|
||||
* name).
|
||||
* If this is not specified, messages from any server may match.
|
||||
* </desc>
|
||||
* <term>Type</term>
|
||||
* <desc>The type of message ... <em>Error</em> or <em>Alert</em>.
|
||||
* If this is not specified, messages of any type may match.
|
||||
* </desc>
|
||||
* <term>Pattern</term>
|
||||
* <desc>An extended regular expression used to match the main text
|
||||
* of the message. See the posix regcomp documentation for details
|
||||
* of enhanced posix regular expressions. If this is not present,
|
||||
* any message text will match.
|
||||
* </desc>
|
||||
* <term>Stop</term>
|
||||
* <desc>A boolean (YES or NO) saying whether rule matching should
|
||||
* stop if this rule is matched. If this is NO (the default) then
|
||||
* after any action associated with this rule is performed, matching
|
||||
* continues at the next rule.<br />
|
||||
* <em>Don't use this option injudiciusly. Try to write your pattern
|
||||
* matching rules so that most messages match a single rule to map
|
||||
* them to a nice readable version, and also match a default rule to
|
||||
* log full details to the technical team.</em>
|
||||
* </desc>
|
||||
* <term>Flush</term>
|
||||
* <desc>A boolean (YES or NO) saying whether stored messages due to
|
||||
* be sent out later should be sent out immediately after processing
|
||||
* this rule. This is useful in the event that some time critical
|
||||
* message must be sent, but should not normally be used.<br />
|
||||
* As a special case, instead of the boolean value, this may take
|
||||
* the value <em>Email</em> or <em>Sms</em> indicating that a flush
|
||||
* should be performed, but only on the specified type of messages.<br />
|
||||
* <strong>beware</strong> The batching mechanism exists to prevent
|
||||
* a single problem triggering floods of messages. You should only
|
||||
* override it using <em>Flush</em> where you are <strong>sure</strong>
|
||||
* that messages triggering the flush will be infrequent.
|
||||
* </desc>
|
||||
* </deflist>
|
||||
* <p>There are two additional fields <em>Extra1</em> and <em>Extra2</em>
|
||||
* which are matched against the message. These patterns do not effect
|
||||
* whether the action of the rule is executed or not, but the text matched
|
||||
* is made available for substitution into replacement messages.
|
||||
* </p>
|
||||
* <p>When a match is found the full message is normally sent to all the
|
||||
* destinations listed in the <em>Email</em> and <em>Sms</em> arrays in
|
||||
* the rule, and logged to all the destinations in the <em>Log</em> array.<br />
|
||||
* However, the <em>Replacement</em> field may be used to specify
|
||||
* a message to be sent in the place of the one received. Within the
|
||||
* <em>Replacement</em> string values enclosed in curly brackets will
|
||||
* be substituted as follows -
|
||||
* </p>
|
||||
* <deflist>
|
||||
* <term>Extra1</term>
|
||||
* <desc>The text in the message matched by the Extra1 pattern (if any)</desc>
|
||||
* <term>Extra2</term>
|
||||
* <desc>The text in the message matched by the Extra2 pattern (if any)</desc>
|
||||
* <term>Host</term>
|
||||
* <desc>The host name of the original message</desc>
|
||||
* <term>Server</term>
|
||||
* <desc>The server name of the original message</desc>
|
||||
* <term>Type</term>
|
||||
* <desc>The type of the original message</desc>
|
||||
* <term>Timestamp</term>
|
||||
* <desc>The timestamp of the original message</desc>
|
||||
* <term>Message</term>
|
||||
* <desc>The text of the original message</desc>
|
||||
* <term>Match</term>
|
||||
* <desc>The text matched by the <em>Pattern</em> if any</desc>
|
||||
* </deflist>
|
||||
* <p>The <em>Log</em> array specifies a list of log destinations which are
|
||||
* normally treated as filenames (stored in the standard log directory).
|
||||
* However, a value beginning 'database:' * is logged to a
|
||||
* database (the default database configured for SQLClient).<br />
|
||||
* After the colon you may place a table name, but if you don't then
|
||||
* the message will be logged to the 'Alert' table.<br />
|
||||
* The values logged in separate fields are the Timestamp, Type, Server, Host,
|
||||
* Extra1, Extra2, and full log text (as produced by the Replacement config)
|
||||
* is written into the Message field of the table after having been truncated
|
||||
* to 200 chars. Because of the truncation limit, it is recommended that
|
||||
* if you are trying to include the original alert {Message} (rather
|
||||
* than rewriting it) the Replacement does not include Timestamp,
|
||||
* Type, Server, Host, Extra1, Extra2 which are already saved in
|
||||
* separate fields, and would take up a lot of the 200 chars, which would
|
||||
* be better used to log the actual message.
|
||||
*
|
||||
* </p>
|
||||
* <p>The <em>Sms</em> array lists phone numbers to which Sms alerts are
|
||||
* to be sent.
|
||||
* </p>
|
||||
* <p>The <em>Email</em> array lists email addresses to which email alerts are
|
||||
* to be sent.<br />
|
||||
* An optional 'Subject' field may be present in the rule ... this is used
|
||||
* to specify that the is to be tagged with the given subject line. This
|
||||
* <em>defeats</em> batching of messages in that only messages with the
|
||||
* same subject may be batched in the same email.
|
||||
* </p>
|
||||
*/
|
||||
@implementation EcAlerter : NSObject
|
||||
|
||||
/**
|
||||
* Called to set up or modify the configuration of the alerter.<br />
|
||||
* The dictionary c must contain (keyed on <code>Rules</code> an
|
||||
* array of dictionaries, each of which provides a rule for
|
||||
* delivering some form of alert.<br />
|
||||
* Other values in the configuration are used for standard configuration
|
||||
* of message delivery to the queueing system etc.
|
||||
*/
|
||||
- (BOOL) configure: (NSNotification*)n
|
||||
{
|
||||
NSUserDefaults *d;
|
||||
|
@ -266,14 +142,11 @@ replaceFields(NSDictionary *fields)
|
|||
return [self setRules: [c objectForKey: @"Rules"]];
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache a copy of the Rules with modifications to store information
|
||||
* so we don't need to regenerate it every time we check a message.
|
||||
*/
|
||||
- (BOOL)setRules: (NSArray*)ra
|
||||
- (BOOL) setRules: (NSArray*)ra
|
||||
{
|
||||
NSUInteger i = 0;
|
||||
NSMutableArray *r = AUTORELEASE([ra mutableCopy]);
|
||||
NSUInteger i = 0;
|
||||
NSMutableArray *r = AUTORELEASE([ra mutableCopy]);
|
||||
|
||||
for (i = 0; i < [r count]; i++)
|
||||
{
|
||||
NSMutableDictionary *md;
|
||||
|
@ -433,9 +306,6 @@ replaceFields(NSDictionary *fields)
|
|||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called to flush any batched email messages.
|
||||
*/
|
||||
- (void) flushEmail
|
||||
{
|
||||
NSDictionary *destinations;
|
||||
|
@ -472,9 +342,6 @@ replaceFields(NSDictionary *fields)
|
|||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called periodically to flush any batched sms messages.
|
||||
*/
|
||||
- (void) flushSms
|
||||
{
|
||||
NS_DURING
|
||||
|
@ -488,28 +355,248 @@ replaceFields(NSDictionary *fields)
|
|||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This method handles error/alert messages. It is able to handle
|
||||
* multiple (newline separated messages.
|
||||
* </p>
|
||||
* <p>Each message must be a line of the format -<br />
|
||||
* serverName(hostName): YYYY-MM-DD hh:mm:ss.mmm szzzz type - text
|
||||
* </p>
|
||||
* <p>Each message is matched against each rule in the <em>Rules</em>
|
||||
* configuration in turn, and the first match found is used. The
|
||||
* message is sent to the people listed in the <code>Email</code> and
|
||||
* <code>Sms</code> entries in the rule (which may be either single
|
||||
* names or arryas of names).
|
||||
* </p>
|
||||
*/
|
||||
- (void) handleInfo: (NSString*)str
|
||||
- (void) handleEvent: (NSString*)text
|
||||
withHost: (NSString*)hostName
|
||||
andServer: (NSString*)serverName
|
||||
timestamp: (NSString*)timestamp
|
||||
immediate: (BOOL)immediate
|
||||
{
|
||||
NSArray *a;
|
||||
unsigned int i;
|
||||
NSMutableDictionary *m;
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
NSUInteger i;
|
||||
NSString *type;
|
||||
NSMutableDictionary *m;
|
||||
|
||||
|
||||
if (YES == immediate)
|
||||
{
|
||||
type = @"Alert";
|
||||
}
|
||||
else
|
||||
{
|
||||
type = @"Error";
|
||||
}
|
||||
for (i = 0; i < [rules count]; i++)
|
||||
{
|
||||
NSDictionary *d = [rules objectAtIndex: i];
|
||||
NSString *match = nil;
|
||||
Regex *e;
|
||||
NSString *s;
|
||||
id o;
|
||||
|
||||
s = [d objectForKey: @"Type"];
|
||||
if (s != nil && [s isEqualToString: type] == NO)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
e = [d objectForKey: @"ServerRegex"];
|
||||
if (e != nil && [e match: serverName] == nil)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
e = [d objectForKey: @"HostRegex"];
|
||||
if (e != nil && [e match: hostName] == nil)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
e = [d objectForKey: @"PatternRegex"];
|
||||
if (e != nil && (match = [e match: text]) == nil)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
|
||||
m = [NSMutableDictionary new];
|
||||
|
||||
/*
|
||||
* If the Extra1 or Extra2 patterns are matched,
|
||||
* The matching strings are made available for
|
||||
* substitution into the replacement message.
|
||||
*/
|
||||
[m removeObjectForKey: @"Extra1"];
|
||||
e = [d objectForKey: @"Extra1Regex"];
|
||||
if (e != nil && (match = [e match: text]) != nil)
|
||||
{
|
||||
[m setObject: match forKey: @"Extra1"];
|
||||
}
|
||||
|
||||
[m removeObjectForKey: @"Extra2"];
|
||||
e = [d objectForKey: @"Extra2Regex"];
|
||||
if (e != nil && (match = [e match: text]) != nil)
|
||||
{
|
||||
[m setObject: match forKey: @"Extra2"];
|
||||
}
|
||||
|
||||
/* We set the Replacement later, because if it is not
|
||||
* set, we want to set a different default for Sms/Email
|
||||
* and database: for Sms/Email logs we want to include
|
||||
* Server, Host, Timestamp, Type and Message (possibly
|
||||
* trying to use as little spaces as possible for Sms,
|
||||
* while trying to display comfortably for Email), while
|
||||
* for database logs we only want to include the
|
||||
* Message.
|
||||
*/
|
||||
|
||||
[m setObject: serverName forKey: @"Server"];
|
||||
[m setObject: hostName forKey: @"Host"];
|
||||
[m setObject: type forKey: @"Type"];
|
||||
[m setObject: timestamp forKey: @"Timestamp"];
|
||||
[m setObject: text forKey: @"Message"];
|
||||
if (match != nil)
|
||||
{
|
||||
[m setObject: match forKey: @"Match"];
|
||||
}
|
||||
|
||||
// NSLog(@"Match produced %@", s);
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
o = [d objectForKey: @"Log"];
|
||||
if ([o isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
if ([o hasPrefix: @"("])
|
||||
{
|
||||
o = [(NSString*)o propertyList];
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [NSArray arrayWithObject: o];
|
||||
}
|
||||
}
|
||||
if (o != nil)
|
||||
{
|
||||
NSString *s = [d objectForKey: @"Replacement"];
|
||||
if (s == nil)
|
||||
{
|
||||
s = @"{Message}";
|
||||
}
|
||||
[m setObject: s forKey: @"Replacement"];
|
||||
|
||||
[self log: m to: o];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception handling database log for rule: %@",
|
||||
localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
o = [d objectForKey: @"Email"];
|
||||
if ([o isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
if ([o hasPrefix: @"("])
|
||||
{
|
||||
o = [(NSString*)o propertyList];
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [NSArray arrayWithObject: o];
|
||||
}
|
||||
}
|
||||
if (o != nil)
|
||||
{
|
||||
NSString *s = [d objectForKey: @"Subject"];
|
||||
|
||||
if (s != nil)
|
||||
{
|
||||
[m setObject: s forKey: @"Subject"];
|
||||
}
|
||||
|
||||
s = [d objectForKey: @"Replacement"];
|
||||
if (s == nil)
|
||||
{
|
||||
/* Full details. */
|
||||
s = @"{Server}({Host}): {Timestamp} {Type} - {Message}";
|
||||
}
|
||||
[m setObject: s forKey: @"Replacement"];
|
||||
|
||||
[self mail: m to: o];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception handling Email send for rule: %@",
|
||||
localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
o = [d objectForKey: @"Sms"];
|
||||
if ([o isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
if ([o hasPrefix: @"("])
|
||||
{
|
||||
o = [(NSString*)o propertyList];
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [NSArray arrayWithObject: o];
|
||||
}
|
||||
}
|
||||
if (o != nil)
|
||||
{
|
||||
NSString *s = [d objectForKey: @"Replacement"];
|
||||
if (s == nil)
|
||||
{
|
||||
/* Use few spaces so that more of the
|
||||
* message fits into an Sms. */
|
||||
s = @"{Server}({Host}):{Timestamp} {Type}-{Message}";
|
||||
}
|
||||
[m setObject: s forKey: @"Replacement"];
|
||||
|
||||
[self sms: m to: o];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception handling Sms send for rule: %@",
|
||||
localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
RELEASE(m);
|
||||
|
||||
s = [d objectForKey: @"Flush"];
|
||||
if (s != nil)
|
||||
{
|
||||
if ([s caseInsensitiveCompare: @"Email"] == NSOrderedSame)
|
||||
{
|
||||
[self flushEmail];
|
||||
}
|
||||
else if ([s caseInsensitiveCompare: @"Sms"] == NSOrderedSame)
|
||||
{
|
||||
[self flushSms];
|
||||
}
|
||||
else if ([s boolValue] == YES)
|
||||
{
|
||||
[self flushSms];
|
||||
[self flushEmail];
|
||||
}
|
||||
}
|
||||
|
||||
if ([[d objectForKey: @"Stop"] boolValue] == YES)
|
||||
{
|
||||
break; // Don't want to perform any more matches.
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Problem in handleInfo:'%@' ... %@", text, localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
- (void) handleInfo: (NSString*)str
|
||||
{
|
||||
NS_DURING
|
||||
{
|
||||
NSArray *a;
|
||||
NSUInteger i;
|
||||
|
||||
a = [str componentsSeparatedByString: @"\n"];
|
||||
for (i = 0; i < [a count]; i++)
|
||||
{
|
||||
|
@ -518,9 +605,8 @@ replaceFields(NSDictionary *fields)
|
|||
NSString *timestamp;
|
||||
NSString *serverName;
|
||||
NSString *hostName;
|
||||
NSString *type = @"Error";
|
||||
BOOL immediate;
|
||||
unsigned pos;
|
||||
unsigned j;
|
||||
|
||||
str = inf;
|
||||
if ([str length] == 0)
|
||||
|
@ -558,222 +644,21 @@ replaceFields(NSDictionary *fields)
|
|||
{
|
||||
continue; // Not an alert or error
|
||||
}
|
||||
type = @"Error";
|
||||
immediate = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = @"Alert";
|
||||
immediate = YES;
|
||||
}
|
||||
timestamp = [str substringToIndex: r.location];
|
||||
|
||||
str = [str substringFromIndex: NSMaxRange(r)];
|
||||
|
||||
for (j = 0; j < [rules count]; j++)
|
||||
{
|
||||
NSDictionary *d = [rules objectAtIndex: j];
|
||||
NSString *match = nil;
|
||||
Regex *e;
|
||||
NSString *s;
|
||||
id o;
|
||||
|
||||
s = [d objectForKey: @"Type"];
|
||||
if (s != nil && [s isEqualToString: type] == NO)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
e = [d objectForKey: @"ServerRegex"];
|
||||
if (e != nil && [e match: serverName] == nil)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
e = [d objectForKey: @"HostRegex"];
|
||||
if (e != nil && [e match: hostName] == nil)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
e = [d objectForKey: @"PatternRegex"];
|
||||
if (e != nil && (match = [e match: str]) == nil)
|
||||
{
|
||||
continue; // Not a match.
|
||||
}
|
||||
|
||||
m = [NSMutableDictionary new];
|
||||
|
||||
/*
|
||||
* If the Extra1 or Extra2 patterns are matched,
|
||||
* The matching strings are made available for
|
||||
* substitution inot the replacement message.
|
||||
*/
|
||||
[m removeObjectForKey: @"Extra1"];
|
||||
e = [d objectForKey: @"Extra1Regex"];
|
||||
if (e != nil && (match = [e match: str]) != nil)
|
||||
{
|
||||
[m setObject: match forKey: @"Extra1"];
|
||||
}
|
||||
|
||||
[m removeObjectForKey: @"Extra2"];
|
||||
e = [d objectForKey: @"Extra2Regex"];
|
||||
if (e != nil && (match = [e match: str]) != nil)
|
||||
{
|
||||
[m setObject: match forKey: @"Extra2"];
|
||||
}
|
||||
|
||||
/* We set the Replacement later, because if it is not
|
||||
* set, we want to set a different default for Sms/Email
|
||||
* and database: for Sms/Email logs we want to include
|
||||
* Server, Host, Timestamp, Type and Message (possibly
|
||||
* trying to use as little spaces as possible for Sms,
|
||||
* while trying to display comfortably for Email), while
|
||||
* for database logs we only want to include the
|
||||
* Message.
|
||||
*/
|
||||
|
||||
[m setObject: serverName forKey: @"Server"];
|
||||
[m setObject: hostName forKey: @"Host"];
|
||||
[m setObject: type forKey: @"Type"];
|
||||
[m setObject: timestamp forKey: @"Timestamp"];
|
||||
[m setObject: str forKey: @"Message"];
|
||||
if (match != nil)
|
||||
{
|
||||
[m setObject: match forKey: @"Match"];
|
||||
}
|
||||
|
||||
// NSLog(@"Match produced %@", s);
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
o = [d objectForKey: @"Log"];
|
||||
if ([o isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
if ([o hasPrefix: @"("])
|
||||
{
|
||||
o = [(NSString*)o propertyList];
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [NSArray arrayWithObject: o];
|
||||
}
|
||||
}
|
||||
if (o != nil)
|
||||
{
|
||||
NSString *s = [d objectForKey: @"Replacement"];
|
||||
if (s == nil)
|
||||
{
|
||||
s = @"{Message}";
|
||||
}
|
||||
[m setObject: s forKey: @"Replacement"];
|
||||
|
||||
[self log: m to: o];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception handling database log for rule: %@",
|
||||
localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
o = [d objectForKey: @"Email"];
|
||||
if ([o isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
if ([o hasPrefix: @"("])
|
||||
{
|
||||
o = [(NSString*)o propertyList];
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [NSArray arrayWithObject: o];
|
||||
}
|
||||
}
|
||||
if (o != nil)
|
||||
{
|
||||
NSString *s = [d objectForKey: @"Subject"];
|
||||
|
||||
if (s != nil)
|
||||
{
|
||||
[m setObject: s forKey: @"Subject"];
|
||||
}
|
||||
|
||||
s = [d objectForKey: @"Replacement"];
|
||||
if (s == nil)
|
||||
{
|
||||
/* Full details. */
|
||||
s = @"{Server}({Host}): {Timestamp} {Type} - {Message}";
|
||||
}
|
||||
[m setObject: s forKey: @"Replacement"];
|
||||
|
||||
[self mail: m to: o];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception handling Email send for rule: %@",
|
||||
localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
o = [d objectForKey: @"Sms"];
|
||||
if ([o isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
if ([o hasPrefix: @"("])
|
||||
{
|
||||
o = [(NSString*)o propertyList];
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [NSArray arrayWithObject: o];
|
||||
}
|
||||
}
|
||||
if (o != nil)
|
||||
{
|
||||
NSString *s = [d objectForKey: @"Replacement"];
|
||||
if (s == nil)
|
||||
{
|
||||
/* Use few spaces so that more of the
|
||||
* message fits into an Sms. */
|
||||
s = @"{Server}({Host}):{Timestamp} {Type}-{Message}";
|
||||
}
|
||||
[m setObject: s forKey: @"Replacement"];
|
||||
|
||||
[self sms: m to: o];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Exception handling Sms send for rule: %@",
|
||||
localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
RELEASE(m);
|
||||
|
||||
s = [d objectForKey: @"Flush"];
|
||||
if (s != nil)
|
||||
{
|
||||
if ([s caseInsensitiveCompare: @"Email"] == NSOrderedSame)
|
||||
{
|
||||
[self flushEmail];
|
||||
}
|
||||
else if ([s caseInsensitiveCompare: @"Sms"] == NSOrderedSame)
|
||||
{
|
||||
[self flushSms];
|
||||
}
|
||||
else if ([s boolValue] == YES)
|
||||
{
|
||||
[self flushSms];
|
||||
[self flushEmail];
|
||||
}
|
||||
}
|
||||
|
||||
if ([[d objectForKey: @"Stop"] boolValue] == YES)
|
||||
{
|
||||
break; // Don't want to perform any more matches.
|
||||
}
|
||||
}
|
||||
[self handleEvent: str
|
||||
withHost: hostName
|
||||
andServer: serverName
|
||||
timestamp: timestamp
|
||||
immediate: immediate];
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
|
@ -802,9 +687,6 @@ replaceFields(NSDictionary *fields)
|
|||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by -handleInfo: to log a message to an array of destinations.
|
||||
*/
|
||||
- (void) log: (NSMutableDictionary*)m to: (NSArray*)destinations
|
||||
{
|
||||
NSEnumerator *e = [destinations objectEnumerator];
|
||||
|
@ -821,11 +703,6 @@ replaceFields(NSDictionary *fields)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by -handleInfo: to pass a message to an array of destinations.
|
||||
* The message is actually appended to any cached messages for those
|
||||
* destinations ... and the cache is periodically flushed.
|
||||
*/
|
||||
- (void) mail: (NSMutableDictionary*)m to: (NSArray*)destinations
|
||||
{
|
||||
NSEnumerator *e = [destinations objectEnumerator];
|
||||
|
@ -890,12 +767,6 @@ replaceFields(NSDictionary *fields)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by -handleInfo: to pass a message to an array of destinations.
|
||||
* The message replaces any cached messages for those
|
||||
* destinations (and has a count of the lost messages noted) ... and
|
||||
* the cache is periodically flushed.
|
||||
*/
|
||||
- (void) sms: (NSMutableDictionary*)m to: (NSArray*)destinations
|
||||
{
|
||||
NSEnumerator *e = [destinations objectEnumerator];
|
||||
|
@ -947,9 +818,6 @@ replaceFields(NSDictionary *fields)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for the periodic calling of -flushEmail and -flushSms
|
||||
*/
|
||||
- (void) timeout: (NSTimer*)t
|
||||
{
|
||||
[self flushSms];
|
||||
|
|
Loading…
Reference in a new issue