Re: [Exim] Is Exin SNMP Aware?

Top Page
Delete this message
Reply to this message
Author: Theo E. Schlossnagle
Date:  
To: Philip Hazel
CC: Kevin Sindhu, Sheldon Hearn, Cliff Savage, exim-users
Subject: Re: [Exim] Is Exin SNMP Aware?
Philip Hazel wrote:
> On Fri, 24 Aug 2001, Theo E. Schlossnagle wrote:
>
>
>>I wrote a while back that it would be REALLY nice to see a modular logging
>>system in Exim (fingers crossed for v4). If you set up a single loadable
>>module support that can accept several loggin mechanisms (chains/cascades like
>>Apache's module hook system) we have a lot of possibilities for FAST,
>>effecient SNMP support without code changes to Exim at all.
>>
>
> I'm not currently planning anything new for Exim 4. Can you not do what
> you want by using syslog and directing it to send the data where you
> want? (I'm no expert on syslog, so don't know its limitations.)


Sorry for the latent response, but I have been away from email. Can I do what
I want with syslog? Yes. Is it the right way to do it? I don't believe so.
It is awkward (other processes use syslog for important things, changing its
functionality is not a great idea) and cumbersome (you have an extra process
in the way)

I think the loadable module, with hooks is a much cleaner approach. I have
patch lying around for exim 3.22 that did this (worked under linux, but should
be hard to stretch to *BSD and Solaris). I didn't do it in an ideal way
because my goal was to make the patch _as small as possible_ so that I could
easily maintain against new releases.

The code that I wront was very simple.

I added a logging structure:

typedef struct _logging_infrastructure {
   LogHookFunc     log_init;  /* Gets called on load */
   LogHookFunc     log_reception;
   LogHookFunc     log_attempt;
   LogHookFunc     log_transient_failure;
   LogHookFunc     log_permanent_failure;
   LogHookFunc     log_delivery;
   LogHookFunc     log_close; /* Gets called on cleanup (before exit) */
} logging_infrastructure;


I added an option to exim's conf file that said:

load_logger = filename.so/logstructname:filename2.so/logstructname2

This dlopened and dlsymed the appropriate structures onto a list of "loggers".
I also called the log_init hook for each if not NULL.

Then, I went into the exim code and looked for where exim prints: receptions,
delivery attempts, transient and permanent failures and successful deliveries.
I preceeded each log statement with:

loggedelsewhere=0;
for(i=0;i<numloggers;i++)
loggedelsewhere = loggers[i]->log_appropriate_hook(args);
if(loggedelsewhere) break;
}
if(!loggedelseshere) {
original logging statement here
}

Then, call the log_close hook for each logger before exit and you have
yourself and simple loadable logging infrastructure.

Now, each hook can return true or false (nonzero or zero). If it returns
true, it stops and logs no more (doesn't fall through to any subsequent
loggers or the default logging mechanism).

This is not the ideal way to do things, just very very easy to maintain and
understand. Ideally, the log_init hook would go a register itself with exim
instead of vice versa. This would allow exim to add more types of hooks and
the programs modules would not need to be ported or recompiled. But... that
was more work and this worked well for me.
--
Theo Schlossnagle
1024D/82844984/95FD 30F1 489E 4613 F22E 491A 7E88 364C 8284 4984
2047R/33131B65/71 F7 95 64 49 76 5D BA 3D 90 B9 9F BE 27 24 E7