From: Rafael Sadowski Subject: Re: httpd: add timestamps to fastcgi error log To: tech@openbsd.org Cc: Claudio Jeker Date: Mon, 2 Nov 2026 09:58:09 +0100 On Sun Nov 01, 2026 at 06:59:48PM +0100, Rafael Sadowski wrote: > I don't suppose anyone has ever tried to debug their error logs. > > This diff changes the log from: > > error.cgi: lab test error, GET /cgi-bin/error.cgi > > to: > > 01/Nov/2026:18:53:55 +0100: error.cgi: lab test error, GET /cgi-bin/error.cgi > > Does anyone have a better idea for a syntax? OK? > > Rafael > Following feedback, here is the next iteration. This time, ONLY the error log, including the format as per "syslogd -Z": 2026-11-02T08:49:40.036Z: error.cgi: lab test error, GET /cgi-bin/error.cgi I don’t want to change the access log at the moment! commit 8496842a679db367ba919ba9e4ee1b16565b506f Author: Rafael Sadowski Date: Sun Nov 1 15:18:04 2026 +0100 httpd: add timestamps to fastcgi error log When not logging to syslog, prefix FastCGI stderr output with a UTC timestamp in the same format syslogd -Z uses. diff --git a/httpd.h b/httpd.h index a2defd9..0fbad1b 100644 --- a/httpd.h +++ b/httpd.h @@ -696,6 +696,7 @@ int server_foreach(int (*)(struct server *, struct server_config *, void *), void *); struct server *server_byname(struct server *); struct server *server_bysocket(struct server *); +int server_current_time(char *, size_t); SPLAY_PROTOTYPE(client_tree, client, clt_nodes, server_client_cmp); diff --git a/server.c b/server.c index b32a077..ea53802 100644 --- a/server.c +++ b/server.c @@ -1560,4 +1560,26 @@ server_client_cmp(struct client *a, struct client *b) return ((int)a->clt_id - b->clt_id); } +int +server_current_time(char *timestamp, size_t len) +{ + struct tm tm; + struct timeval now; + size_t l; + int n; + + if (gettimeofday(&now, NULL) == -1) + return (-1); + if (gmtime_r(&now.tv_sec, &tm) == NULL) + return (-1); + if ((l = strftime(timestamp, len, "%FT%T", &tm)) == 0) + return (-1); + n = snprintf(timestamp + l, len - l, ".%03ldZ", + (long)now.tv_usec / 1000); + if (n < 0 || (size_t)n >= len - l) + return (-1); + + return (0); +} + SPLAY_GENERATE(client_tree, client, clt_nodes, server_client_cmp); diff --git a/server_fcgi.c b/server_fcgi.c index 2428adb..ef58c3f 100644 --- a/server_fcgi.c +++ b/server_fcgi.c @@ -85,6 +85,7 @@ int server_fcgi_writechunk(struct client *); int server_fcgi_getheaders(struct client *); int fcgi_add_param(struct server_fcgi_param *, const char *, const char *, struct client *); +void server_fcgi_err_log(struct client *); int server_fcgi(struct httpd *env, struct client *clt) @@ -512,6 +513,32 @@ server_fcgi_error(struct bufferevent *bev, short error, void *arg) server_file_error(bev, error, arg); } +void +server_fcgi_err_log(struct client *clt) +{ + char tstamp[33]; + struct server_config *srv_conf; + size_t len; + char *msg; + + if ((srv_conf = clt->clt_srv_conf) == NULL) + return; + + if ((len = EVBUFFER_LENGTH(clt->clt_srvevb)) == 0) + return; + + if ((msg = get_string(EVBUFFER_DATA(clt->clt_srvevb), len)) == NULL) + return; + + if ((srv_conf->flags & SRVFLAG_SYSLOG) == 0 && + server_current_time(tstamp, sizeof(tstamp)) == 0) { + server_sendlog(srv_conf, IMSG_LOG_ERROR, "%s: %s", tstamp, msg); + } else { + server_sendlog(srv_conf, IMSG_LOG_ERROR, "%s", msg); + } + free(msg); +} + void server_fcgi_read(struct bufferevent *bev, void *arg) { @@ -519,7 +546,6 @@ server_fcgi_read(struct bufferevent *bev, void *arg) struct client *clt = (struct client *)arg; struct fcgi_record_header *h; size_t len; - char *ptr; do { len = bufferevent_read(bev, buf, clt->clt_fcgi.toread); @@ -561,15 +587,7 @@ server_fcgi_read(struct bufferevent *bev, void *arg) case FCGI_READ_CONTENT: switch (clt->clt_fcgi.type) { case FCGI_STDERR: - if (EVBUFFER_LENGTH(clt->clt_srvevb) > 0 && - (ptr = get_string( - EVBUFFER_DATA(clt->clt_srvevb), - EVBUFFER_LENGTH(clt->clt_srvevb))) != - NULL) { - server_sendlog(clt->clt_srv_conf, - IMSG_LOG_ERROR, "%s", ptr); - free(ptr); - } + server_fcgi_err_log(clt); break; case FCGI_STDOUT: ++clt->clt_chunk;