Name
Logger
Synopsis
int module_logger(request_rec *pRec)
Now that the request has been processed and
the dust has settled, you may want to log the request in some way.
Here’s your chance to do that. Although the core
stops running the logger function as soon as a module returns
something other than OK
or
DECLINED
, that is rarely done, as there is no way
to know whether another module needs to log something.
Although mod_log_agent.c is more or less out of date since mod_log_config.c was introduced, it makes a nice, compact example. See Example 21-23.
Example
int agent_log_transaction(request_rec *orig) { agent_log_state *cls = ap_get_module_config (orig->server->module_config, &agent_log_module); char str[HUGE_STRING_LEN]; char *agent; request_rec *r; if(cls->agent_fd <0) return OK; for (r = orig; r->next; r = r->next) continue; if (*cls->fname == '\0'. /* Don't log agent */ return DECLINED; agent = table_get(orig->headers_in, "User-Agent"); if(agent != NULL) { sprintf(str, "%s\n", agent); write(cls->agent_fd, str, strlen(str)); } return OK; }
This is not a good example of programming practice. With its
fixed-size buffer str
, it leaves a gaping security
hole. It wouldn’t be enough simply to split the
write
into two parts to avoid this problem.
Because the log file is shared among all server processes, the
write
must be atomic, or the log file could get
mangled by overlapping write
s.
mod_log_config.c carefully avoids this problem.
Unfortunately, mod_log_agent.c ...
Get Apache: The Definitive Guide, 3rd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.