⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 access_log.c

📁 -
💻 C
字号:
/* * $Id: access_log.c,v 1.49.2.1 1999/04/19 01:21:20 wessels Exp $ * * DEBUG: section 46    Access Log * AUTHOR: Duane Wessels * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"static void accessLogOpen(const char *fname);static char *log_quote(const char *header);static void accessLogSquid(AccessLogEntry * al, MemBuf * mb);static void accessLogCommon(AccessLogEntry * al, MemBuf * mb);#if MULTICAST_MISS_STREAMstatic int mcast_miss_fd = -1;static struct sockaddr_in mcast_miss_to;static void mcast_encode(unsigned int *, size_t, const unsigned int *);#endifconst char *log_tags[] ={    "NONE",    "TCP_HIT",    "TCP_MISS",    "TCP_REFRESH_HIT",    "TCP_REF_FAIL_HIT",    "TCP_REFRESH_MISS",    "TCP_CLIENT_REFRESH_MISS",    "TCP_IMS_HIT",    "TCP_SWAPFAIL_MISS",    "TCP_NEGATIVE_HIT",    "TCP_MEM_HIT",    "TCP_DENIED",    "TCP_OFFLINE_HIT",    "UDP_HIT",    "UDP_MISS",    "UDP_DENIED",    "UDP_INVALID",    "UDP_MISS_NOFETCH",    "ICP_QUERY",    "LOG_TYPE_MAX"};#if FORW_VIA_DBtypedef struct {    char *key;    void *next;    int n;} fvdb_entry;static hash_table *via_table = NULL;static hash_table *forw_table = NULL;static void fvdbInit(void);static void fvdbDumpTable(StoreEntry * e, hash_table * hash);static void fvdbCount(hash_table * hash, const char *key);static OBJH fvdbDumpVia;static OBJH fvdbDumpForw;static FREE fvdbFreeEntry;static void fvdbClear(void);#endifstatic int LogfileStatus = LOG_DISABLE;static int LogfileFD = -1;static char LogfileName[SQUID_MAXPATHLEN];#define LOG_BUF_SZ (MAX_URL<<2)static const char c2x[] ="000102030405060708090a0b0c0d0e0f""101112131415161718191a1b1c1d1e1f""202122232425262728292a2b2c2d2e2f""303132333435363738393a3b3c3d3e3f""404142434445464748494a4b4c4d4e4f""505152535455565758595a5b5c5d5e5f""606162636465666768696a6b6c6d6e6f""707172737475767778797a7b7c7d7e7f""808182838485868788898a8b8c8d8e8f""909192939495969798999a9b9c9d9e9f""a0a1a2a3a4a5a6a7a8a9aaabacadaeaf""b0b1b2b3b4b5b6b7b8b9babbbcbdbebf""c0c1c2c3c4c5c6c7c8c9cacbcccdcecf""d0d1d2d3d4d5d6d7d8d9dadbdcdddedf""e0e1e2e3e4e5e6e7e8e9eaebecedeeef""f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";/* log_quote -- URL-style encoding on MIME headers. */static char *log_quote(const char *header){    int c;    int i;    char *buf;    char *buf_cursor;    if (header == NULL) {	buf = xcalloc(1, 1);	*buf = '\0';	return buf;    }    buf = xcalloc((strlen(header) * 3) + 1, 1);    buf_cursor = buf;    /*     * We escape: \x00-\x1F"#%;<>?{}|\\\\^~`\[\]\x7F-\xFF      * which is the default escape list for the CPAN Perl5 URI module     * modulo the inclusion of space (x40) to make the raw logs a bit     * more readable.     */    while ((c = *(const unsigned char *) header++) != '\0') {	if (c <= 0x1F	    || c >= 0x7F	    || c == '"'	    || c == '#'	    || c == '%'	    || c == ';'	    || c == '<'	    || c == '>'	    || c == '?'	    || c == '{'	    || c == '}'	    || c == '|'	    || c == '\\'	    || c == '^'	    || c == '~'	    || c == '`'	    || c == '['	    || c == ']') {	    *buf_cursor++ = '%';	    i = c * 2;	    *buf_cursor++ = c2x[i];	    *buf_cursor++ = c2x[i + 1];	} else {	    *buf_cursor++ = (char) c;	}    }    *buf_cursor = '\0';    return buf;}static voidaccessLogSquid(AccessLogEntry * al, MemBuf * mb){    const char *client = NULL;    if (Config.onoff.log_fqdn)	client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);    if (client == NULL)	client = inet_ntoa(al->cache.caddr);    memBufPrintf(mb, "%9d.%03d %6d %s %s/%03d %d %s %s %s %s%s/%s %s",	(int) current_time.tv_sec,	(int) current_time.tv_usec / 1000,	al->cache.msec,	client,	log_tags[al->cache.code],	al->http.code,	al->cache.size,	al->private.method_str,	al->url,	al->cache.ident,	al->hier.ping.timedout ? "TIMEOUT_" : "",	hier_strings[al->hier.code],	al->hier.host,	al->http.content_type);}static voidaccessLogCommon(AccessLogEntry * al, MemBuf * mb){    const char *client = NULL;    if (Config.onoff.log_fqdn)	client = fqdncache_gethostbyaddr(al->cache.caddr, 0);    if (client == NULL)	client = inet_ntoa(al->cache.caddr);    memBufPrintf(mb, "%s %s - [%s] \"%s %s HTTP/%.1f\" %d %d %s:%s",	client,	al->cache.ident,	mkhttpdlogtime(&squid_curtime),	al->private.method_str,	al->url,	al->http.version,	al->http.code,	al->cache.size,	log_tags[al->cache.code],	hier_strings[al->hier.code]);}static voidaccessLogOpen(const char *fname){    assert(fname);    xstrncpy(LogfileName, fname, SQUID_MAXPATHLEN);    LogfileFD = file_open(LogfileName, O_WRONLY | O_CREAT, NULL, NULL, NULL);    if (LogfileFD == DISK_ERROR) {	debug(50, 0) ("%s: %s\n", LogfileName, xstrerror());	fatalf("Cannot open %s: %s", LogfileName, xstrerror());    }    LogfileStatus = LOG_ENABLE;}voidaccessLogLog(AccessLogEntry * al){    MemBuf mb;    char *xbuf = NULL;    LOCAL_ARRAY(char, ident_buf, USER_IDENT_SZ);    if (LogfileStatus != LOG_ENABLE)	return;    if (al->url == NULL)	al->url = dash_str;    if (!al->http.content_type || *al->http.content_type == '\0')	al->http.content_type = dash_str;    if (!al->cache.ident || *al->cache.ident == '\0') {	al->cache.ident = dash_str;    } else {	xstrncpy(ident_buf, rfc1738_escape(al->cache.ident), USER_IDENT_SZ);	al->cache.ident = ident_buf;    }    if (al->icp.opcode)	al->private.method_str = icp_opcode_str[al->icp.opcode];    else	al->private.method_str = RequestMethodStr[al->http.method];    if (al->hier.host[0] == '\0')	xstrncpy(al->hier.host, dash_str, SQUIDHOSTNAMELEN);    memBufDefInit(&mb);    if (Config.onoff.common_log)	accessLogCommon(al, &mb);    else	accessLogSquid(al, &mb);    if (Config.onoff.log_mime_hdrs) {	char *ereq = log_quote(al->headers.request);	char *erep = log_quote(al->headers.reply);	memBufPrintf(&mb, " [%s] [%s]\n", ereq, erep);	safe_free(ereq);	safe_free(erep);    } else {	memBufPrintf(&mb, "\n");    }    file_write_mbuf(LogfileFD, -1, mb, NULL, NULL);    safe_free(xbuf);#if MULTICAST_MISS_STREAM    if (al->cache.code != LOG_TCP_MISS)	(void) 0;    else if (al->http.method != METHOD_GET)	(void) 0;    else if (mcast_miss_fd < 0)	(void) 0;    else {	unsigned int ibuf[365];	size_t isize;	xstrncpy((char *) ibuf, al->url, 364 * sizeof(int));	isize = ((strlen(al->url) + 8) / 8) * 2;	if (isize > 364)	    isize = 364;	mcast_encode((unsigned int *) ibuf, isize,	    (const unsigned int *) Config.mcast_miss.encode_key);	comm_udp_sendto(mcast_miss_fd,	    &mcast_miss_to, sizeof(mcast_miss_to),	    ibuf, isize * sizeof(int));    }#endif}voidaccessLogRotate(void){    int i;    LOCAL_ARRAY(char, from, MAXPATHLEN);    LOCAL_ARRAY(char, to, MAXPATHLEN);    char *fname = NULL;    struct stat sb;#if FORW_VIA_DB    fvdbClear();#endif    if ((fname = LogfileName) == NULL)	return;#ifdef S_ISREG    if (stat(fname, &sb) == 0)	if (S_ISREG(sb.st_mode) == 0)	    return;#endif    debug(46, 1) ("accessLogRotate: Rotating\n");    /* Rotate numbers 0 through N up one */    for (i = Config.Log.rotateNumber; i > 1;) {	i--;	snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1);	snprintf(to, MAXPATHLEN, "%s.%d", fname, i);	rename(from, to);    }    /* Rotate the current log to .0 */    file_close(LogfileFD);	/* always close */    if (Config.Log.rotateNumber > 0) {	snprintf(to, MAXPATHLEN, "%s.%d", fname, 0);	rename(fname, to);    }    /* Reopen the log.  It may have been renamed "manually" */    LogfileFD = file_open(fname, O_WRONLY | O_CREAT, NULL, NULL, NULL);    if (LogfileFD == DISK_ERROR) {	debug(46, 0) ("accessLogRotate: Cannot open logfile: %s\n", fname);	LogfileStatus = LOG_DISABLE;	fatalf("Cannot open %s: %s", fname, xstrerror());    }}voidaccessLogClose(void){    file_close(LogfileFD);}voidhierarchyNote(HierarchyLogEntry * hl,    hier_code code,    const char *cache_peer){    assert(hl != NULL);    hl->code = code;    xstrncpy(hl->host, cache_peer, SQUIDHOSTNAMELEN);}voidaccessLogInit(void){    assert(sizeof(log_tags) == (LOG_TYPE_MAX + 1) * sizeof(char *));    accessLogOpen(Config.Log.access);#if FORW_VIA_DB    fvdbInit();#endif#if MULTICAST_MISS_STREAM    if (Config.mcast_miss.addr.s_addr != no_addr.s_addr) {	memset(&mcast_miss_to, '\0', sizeof(mcast_miss_to));	mcast_miss_to.sin_family = AF_INET;	mcast_miss_to.sin_port = htons(Config.mcast_miss.port);	mcast_miss_to.sin_addr.s_addr = Config.mcast_miss.addr.s_addr;	mcast_miss_fd = comm_open(SOCK_DGRAM,	    0,	    Config.Addrs.udp_incoming,	    Config.mcast_miss.port,	    COMM_NONBLOCKING,	    "Multicast Miss Stream");	if (mcast_miss_fd < 0)	    fatal("Cannot open Multicast Miss Stream Socket");	debug(46, 1) ("Multicast Miss Stream Socket opened on FD %d\n",	    mcast_miss_fd);	mcastSetTtl(mcast_miss_fd, 128);	if (strlen(Config.mcast_miss.encode_key) < 16)	    fatal("mcast_encode_key is too short, must be 16 characters");    }#endif}const char *accessLogTime(time_t t){    struct tm *tm;    static char buf[128];    static time_t last_t = 0;    if (t != last_t) {	tm = localtime(&t);	strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);	last_t = t;    }    return buf;}#if FORW_VIA_DBstatic voidfvdbInit(void){    via_table = hash_create((HASHCMP *) strcmp, 977, hash4);    forw_table = hash_create((HASHCMP *) strcmp, 977, hash4);    cachemgrRegister("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1);    cachemgrRegister("forw_headers", "X-Forwarded-For Request Headers",	fvdbDumpForw, 0, 1);}static voidfvdbCount(hash_table * hash, const char *key){    fvdb_entry *fv;    if (NULL == hash)	return;    fv = hash_lookup(hash, key);    if (NULL == fv) {	fv = xcalloc(1, sizeof(fvdb_entry));	fv->key = xstrdup(key);	hash_join(hash, (hash_link *) fv);    }    fv->n++;}voidfvdbCountVia(const char *key){    fvdbCount(via_table, key);}voidfvdbCountForw(const char *key){    fvdbCount(forw_table, key);}static voidfvdbDumpTable(StoreEntry * e, hash_table * hash){    hash_link *h;    fvdb_entry *fv;    if (hash == NULL)	return;    hash_first(hash);    while ((h = hash_next(hash))) {	fv = (fvdb_entry *) h;	storeAppendPrintf(e, "%9d %s\n", fv->n, fv->key);    }}static voidfvdbDumpVia(StoreEntry * e){    fvdbDumpTable(e, via_table);}static voidfvdbDumpForw(StoreEntry * e){    fvdbDumpTable(e, forw_table);}staticvoidfvdbFreeEntry(void *data){    fvdb_entry *fv = data;    xfree(fv->key);    xfree(fv);}static voidfvdbClear(void){    hashFreeItems(via_table, fvdbFreeEntry);    hashFreeMemory(via_table);    via_table = hash_create((HASHCMP *) strcmp, 977, hash4);    hashFreeItems(forw_table, fvdbFreeEntry);    hashFreeMemory(forw_table);    forw_table = hash_create((HASHCMP *) strcmp, 977, hash4);}#endif#if MULTICAST_MISS_STREAM/* * From http://www.io.com/~paulhart/game/algorithms/tea.html * * size of 'ibuf' must be a multiple of 2. * size of 'key' must be 4. * 'ibuf' is modified in place, encrypted data is written in * network byte order. */static voidmcast_encode(unsigned int *ibuf, size_t isize, const unsigned int *key){    unsigned int y;    unsigned int z;    unsigned int sum;    const unsigned int delta = 0x9e3779b9;    unsigned int n = 32;    const unsigned int k0 = htonl(key[0]);    const unsigned int k1 = htonl(key[1]);    const unsigned int k2 = htonl(key[2]);    const unsigned int k3 = htonl(key[3]);    int i;    for (i = 0; i < isize; i += 2) {	y = htonl(ibuf[i]);	z = htonl(ibuf[i + 1]);	sum = 0;	for (n = 32; n; n--) {	    sum += delta;	    y += (z << 4) + (k0 ^ z) + (sum ^ (z >> 5)) + k1;	    z += (y << 4) + (k2 ^ y) + (sum ^ (y >> 5)) + k3;	}	ibuf[i] = htonl(y);	ibuf[i + 1] = htonl(z);    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -