mirror of https://github.com/omar-polo/gmid.git
allow to change the logging style; introduce some new ones
add `log style <style>'; The old default is called `legacy' now, a new default format is added called `condensed', and `common' and `combined' to mimick Apache httpd and nginx (respectively) are also added.
This commit is contained in:
parent
2a28b04424
commit
abd261d25b
67
gmid.c
67
gmid.c
|
@ -84,11 +84,23 @@ void
|
|||
log_request(struct client *c, int code, const char *meta)
|
||||
{
|
||||
struct conf *conf = c->conf;
|
||||
char tstamp[64], rfc3339[32];
|
||||
char b[GEMINI_URL_LEN];
|
||||
char *fmted;
|
||||
const char *t;
|
||||
struct tm *tm;
|
||||
time_t now;
|
||||
int ec;
|
||||
|
||||
if ((now = time(NULL)) == -1)
|
||||
fatal("time");
|
||||
if ((tm = localtime(&now)) == NULL)
|
||||
fatal("localtime");
|
||||
if (strftime(tstamp, sizeof(tstamp), "%d/%b%Y:%H:%M:%S %z", tm) == 0)
|
||||
fatal("strftime");
|
||||
if (strftime(rfc3339, sizeof(rfc3339), "%FT%T%z", tm) == 0)
|
||||
fatal("strftime");
|
||||
|
||||
if (c->iri.schema != NULL) {
|
||||
/* serialize the IRI */
|
||||
strlcpy(b, c->iri.schema, sizeof(b));
|
||||
|
@ -114,8 +126,59 @@ log_request(struct client *c, int code, const char *meta)
|
|||
strlcpy(b, t, sizeof(b));
|
||||
}
|
||||
|
||||
ec = asprintf(&fmted, "%s:%s GET %s %d %s", c->rhost, c->rserv, b,
|
||||
code, meta);
|
||||
switch (conf->log_format) {
|
||||
case LOG_FORMAT_LEGACY:
|
||||
ec = asprintf(&fmted, "%s:%s GET %s %d %s", c->rhost,
|
||||
c->rserv, b, code, meta);
|
||||
break;
|
||||
|
||||
case LOG_FORMAT_CONDENSED:
|
||||
/*
|
||||
* XXX the first '-' is the remote user name, we
|
||||
* could use the client cert for it.
|
||||
*
|
||||
* XXX it should log the size of the response
|
||||
*/
|
||||
ec = asprintf(&fmted, "%s %s - %s %s 0 %d %s", rfc3339,
|
||||
c->rhost, *c->domain == '\0' ? c->iri.host : c->domain,
|
||||
b, code, meta);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Attempt to be compatible with the default Apache httpd'
|
||||
* LogFormat "%h %l %u %t \"%r\" %>s %b"
|
||||
* see <https://httpd.apache.org/docs/current/mod/mod_log_config.html>
|
||||
*/
|
||||
case LOG_FORMAT_COMMON:
|
||||
/*
|
||||
* XXX the second '-' is the remote user name, we
|
||||
* could use the client cert for it.
|
||||
*
|
||||
* XXX it should log the size of the response.
|
||||
*/
|
||||
ec = asprintf(&fmted, "%s %s - - %s \"%s\" %d 0",
|
||||
*c->domain == '\0' ? c->iri.host : c->domain,
|
||||
c->rhost, tstamp, b, code);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Attempt to be compatible with the default nginx' log_format
|
||||
* combined:
|
||||
* '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
|
||||
*/
|
||||
case LOG_FORMAT_COMBINED:
|
||||
default:
|
||||
/*
|
||||
* XXX the second '-' is the remote user name, we
|
||||
* could use the client cert for it.
|
||||
*
|
||||
* XXX it should log the size of the response.
|
||||
*/
|
||||
ec = asprintf(&fmted, "%s - - [%s] \"%s\" %d 0 \"-\" \"\"",
|
||||
c->rhost, tstamp, b, code);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ec == -1)
|
||||
fatal("asprintf");
|
||||
|
||||
|
|
45
gmid.conf.5
45
gmid.conf.5
|
@ -142,6 +142,51 @@ Log the requests to
|
|||
.Ar file .
|
||||
The path is relative to the
|
||||
.Ic chroot .
|
||||
.It Ic style Ar style
|
||||
Set the logging style, defaults to
|
||||
.Ic condensed .
|
||||
The
|
||||
.Ar style
|
||||
can be one of:
|
||||
.Bl -tag -width Ds
|
||||
.It Ic common
|
||||
Attempt to be compatible with the default Apache httpd log format.
|
||||
Each line is formatted as follows: the matching host name,
|
||||
the remote IP address, one dash
|
||||
.Sq - ,
|
||||
Common Name of the client certificate
|
||||
.Pq if provided, '-' otherwise ,
|
||||
the timestamp of the request, the request URI wrapped in double quotes,
|
||||
the response code and the size of the response.
|
||||
.It Ic combined
|
||||
Attempt to be compatible with the default nginx log format.
|
||||
Each line is formatted as follows: the remote IP address, one dash
|
||||
.Sq - ,
|
||||
Common Name of the client certificate
|
||||
.Pq if provided, '-' otherwise ,
|
||||
the timestamp wrapped in square brackets, the request URI wrapped in
|
||||
double quotes, the response code, the size of the response, a dash
|
||||
wrapped in double quotes and "".
|
||||
The strangness of these two last fields is because Gemini doesn't have
|
||||
the notion of the
|
||||
.Dq Referer
|
||||
header nor the
|
||||
.Dq User-agent .
|
||||
.It Ic condensed
|
||||
The native
|
||||
.Xr gmid 8
|
||||
format since 2.0.
|
||||
Each line is formatted as follows: RFC 3339 date time,
|
||||
remote IP address, Common Name of the client certificate
|
||||
.Pq if provided, '-' otherwise ,
|
||||
the matching host name, the request URI, the size of the response,
|
||||
the response code and meta.
|
||||
.It Ic legacy
|
||||
The pre-2.0 gmid native format.
|
||||
Each line is formatted as follows: the remote IP address and port, the
|
||||
.Sq GET
|
||||
keyword, the request URI, the response code and meta.
|
||||
.El
|
||||
.El
|
||||
.It Ic prefork Ar number
|
||||
Run the specified number of server processes.
|
||||
|
|
8
gmid.h
8
gmid.h
|
@ -90,6 +90,13 @@
|
|||
struct privsep;
|
||||
struct privsep_proc;
|
||||
|
||||
enum log_format {
|
||||
LOG_FORMAT_CONDENSED,
|
||||
LOG_FORMAT_COMMON,
|
||||
LOG_FORMAT_COMBINED,
|
||||
LOG_FORMAT_LEGACY,
|
||||
};
|
||||
|
||||
struct parser {
|
||||
char *iri;
|
||||
struct iri *parsed;
|
||||
|
@ -242,6 +249,7 @@ struct conf {
|
|||
int prefork;
|
||||
int reload;
|
||||
char *log_access;
|
||||
enum log_format log_format;
|
||||
int use_privsep_crypto;
|
||||
|
||||
struct fcgihead fcgi;
|
||||
|
|
23
parse.y
23
parse.y
|
@ -124,16 +124,16 @@ typedef struct {
|
|||
|
||||
%token ACCESS ALIAS AUTO
|
||||
%token BLOCK
|
||||
%token CA CERT CHROOT CLIENT
|
||||
%token CA CERT CHROOT CLIENT COMBINED COMMON CONDENSED
|
||||
%token DEFAULT
|
||||
%token FASTCGI FOR_HOST
|
||||
%token INCLUDE INDEX IPV6
|
||||
%token KEY
|
||||
%token LANG LISTEN LOCATION LOG
|
||||
%token LANG LEGACY LISTEN LOCATION LOG
|
||||
%token OCSP OFF ON
|
||||
%token PARAM PORT PREFORK PROTO PROTOCOLS PROXY
|
||||
%token RELAY_TO REQUIRE RETURN ROOT
|
||||
%token SERVER SNI SOCKET STRIP SYSLOG
|
||||
%token SERVER SNI SOCKET STRIP STYLE SYSLOG
|
||||
%token TCP TOEXT TYPE TYPES
|
||||
%token USE_TLS USER
|
||||
%token VERIFYNAME
|
||||
|
@ -268,6 +268,18 @@ logopt : SYSLOG {
|
|||
free(conf->log_access);
|
||||
conf->log_access = $2;
|
||||
}
|
||||
| STYLE COMMON {
|
||||
conf->log_format = LOG_FORMAT_COMMON;
|
||||
}
|
||||
| STYLE COMBINED {
|
||||
conf->log_format = LOG_FORMAT_COMBINED;
|
||||
}
|
||||
| STYLE CONDENSED {
|
||||
conf->log_format = LOG_FORMAT_CONDENSED;
|
||||
}
|
||||
| STILE LEGACY {
|
||||
conf->log_format = LOG_FORMAT_LEGACY;
|
||||
}
|
||||
;
|
||||
|
||||
vhost : SERVER string {
|
||||
|
@ -603,6 +615,9 @@ static const struct keyword {
|
|||
{"cert", CERT},
|
||||
{"chroot", CHROOT},
|
||||
{"client", CLIENT},
|
||||
{"combined", COMBINED},
|
||||
{"common", COMMON},
|
||||
{"condensed", CONDENSED},
|
||||
{"default", DEFAULT},
|
||||
{"fastcgi", FASTCGI},
|
||||
{"for-host", FOR_HOST},
|
||||
|
@ -611,6 +626,7 @@ static const struct keyword {
|
|||
{"ipv6", IPV6},
|
||||
{"key", KEY},
|
||||
{"lang", LANG},
|
||||
{"legacy", LEGACY},
|
||||
{"listen", LISTEN},
|
||||
{"location", LOCATION},
|
||||
{"log", LOG},
|
||||
|
@ -631,6 +647,7 @@ static const struct keyword {
|
|||
{"sni", SNI},
|
||||
{"socket", SOCKET},
|
||||
{"strip", STRIP},
|
||||
{"style", STYLE},
|
||||
{"syslog", SYSLOG},
|
||||
{"tcp", TCP},
|
||||
{"to-ext", TOEXT},
|
||||
|
|
|
@ -385,10 +385,11 @@ test_log_file() {
|
|||
fetch_hdr /
|
||||
check_reply '20 text/gemini'
|
||||
|
||||
# remove the <ip>:<port> leading part
|
||||
awk '{$1 = ""; print substr($0, 2)}' log > log.edited
|
||||
# remove the date and ip
|
||||
awk '{$1 = ""; $2 = ""; print substr($0, 3)}' log > log.edited
|
||||
|
||||
echo GET gemini://localhost/ 20 text/gemini | cmp -s - log.edited
|
||||
printf '%s\n' '- localhost gemini://localhost/ 0 20 text/gemini' \
|
||||
| cmp -s - log.edited
|
||||
if [ $? -ne 0 ]; then
|
||||
# keep the log for post-mortem analysis
|
||||
return 1
|
||||
|
|
Loading…
Reference in New Issue