access_log.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 46 Access Log */
10 
11 #include "squid.h"
12 #include "AccessLogEntry.h"
13 #include "acl/Checklist.h"
14 #include "sbuf/Algorithms.h"
15 #if USE_ADAPTATION
16 #include "adaptation/Config.h"
17 #endif
18 #include "base/PackableStream.h"
19 #include "CachePeer.h"
20 #include "error/Detail.h"
21 #include "errorpage.h"
22 #include "format/Token.h"
23 #include "globals.h"
24 #include "hier_code.h"
25 #include "HttpReply.h"
26 #include "HttpRequest.h"
27 #include "log/access_log.h"
28 #include "log/Config.h"
29 #include "log/CustomLog.h"
30 #include "log/File.h"
31 #include "log/Formats.h"
32 #include "MemBuf.h"
33 #include "mgr/Registration.h"
34 #include "rfc1738.h"
35 #include "sbuf/SBuf.h"
36 #include "SquidConfig.h"
37 #include "Store.h"
38 
39 #if USE_SQUID_EUI
40 #include "eui/Eui48.h"
41 #include "eui/Eui64.h"
42 #endif
43 
44 #include <unordered_map>
45 
46 #if USE_FORW_VIA_DB
47 
48 using HeaderValueCountsElement = std::pair<const SBuf, uint64_t>;
50 using HeaderValueCounts = std::unordered_map<SBuf, uint64_t, std::hash<SBuf>, std::equal_to<SBuf>, PoolingAllocator<HeaderValueCountsElement> >;
51 
53 static HeaderValueCounts TheViaCounts;
55 static HeaderValueCounts TheForwardedCounts;
56 
57 static OBJH fvdbDumpVia;
58 static OBJH fvdbDumpForwarded;
59 static void fvdbClear(void);
60 static void fvdbRegisterWithCacheManager();
61 #endif
62 
64 
65 void
67 {
68 
69  if (al->url.isEmpty())
70  al->url = Format::Dash;
71 
72  if (!al->http.content_type || *al->http.content_type == '\0')
74 
75  if (al->hier.host[0] == '\0')
77 
78  for (; log; log = log->next) {
79  if (log->aclList && checklist && !checklist->fastCheck(log->aclList).allowed())
80  continue;
81 
82  // The special-case "none" type has no logfile object set
83  if (log->type == Log::Format::CLF_NONE)
84  return;
85 
86  if (log->logfile) {
87  logfileLineStart(log->logfile);
88 
89  switch (log->type) {
90 
92  Log::Format::SquidNative(al, log->logfile);
93  break;
94 
96  Log::Format::HttpdCombined(al, log->logfile);
97  break;
98 
100  Log::Format::HttpdCommon(al, log->logfile);
101  break;
102 
104  Log::Format::SquidReferer(al, log->logfile);
105  break;
106 
108  Log::Format::SquidUserAgent(al, log->logfile);
109  break;
110 
113  break;
114 
115 #if ICAP_CLIENT
117  Log::Format::SquidIcap(al, log->logfile);
118  break;
119 #endif
120 
121  default:
122  fatalf("Unknown log format %d\n", log->type);
123  break;
124  }
125 
126  logfileLineEnd(log->logfile);
127  }
128 
129  // NP: WTF? if _any_ log line has no checklist ignore the following ones?
130  if (!checklist)
131  break;
132  }
133 }
134 
135 void
137 {
138  if (LogfileStatus != LOG_ENABLE)
139  return;
140 
141  accessLogLogTo(Config.Log.accesslogs, al, checklist);
142 }
143 
144 void
146 {
147  CustomLog *log;
148 #if USE_FORW_VIA_DB
149 
150  fvdbClear();
151 #endif
152 
153  for (log = Config.Log.accesslogs; log; log = log->next) {
154  log->rotate();
155  }
156 }
157 
158 void
160 {
161  CustomLog *log;
162 
163  for (log = Config.Log.accesslogs; log; log = log->next) {
164  if (log->logfile) {
165  logfileClose(log->logfile);
166  log->logfile = nullptr;
167  }
168  }
169 }
170 
172  code(HIER_NONE),
173  cd_lookup(LOOKUP_NONE),
174  n_choices(0),
175  n_ichoices(0),
176  peer_reply_status(Http::scNone),
177  tcpServer(nullptr),
178  bodyBytesRead(-1)
179 {
180  memset(host, '\0', SQUIDHOSTNAMELEN);
181  memset(cd_host, '\0', SQUIDHOSTNAMELEN);
182 
183  peer_select_start.tv_sec =0;
184  peer_select_start.tv_usec =0;
185 
186  store_complete_stop.tv_sec =0;
187  store_complete_stop.tv_usec =0;
188 
189  clearPeerNotes();
190 }
191 
192 void
194 {
195  clearPeerNotes();
196 
197  tcpServer = server;
198  if (tcpServer == nullptr) {
199  code = HIER_NONE;
200  xstrncpy(host, requestedHost, sizeof(host));
201  } else {
203 
204  if (tcpServer->getPeer()) {
205  // went to peer, log peer host name
206  xstrncpy(host, tcpServer->getPeer()->name, sizeof(host));
207  } else {
208  xstrncpy(host, requestedHost, sizeof(host));
209  }
210  }
211 }
212 
214 void
216 {
217  peer_last_read_.tv_sec = 0;
218  peer_last_read_.tv_usec = 0;
219 
220  peer_last_write_.tv_sec = 0;
221  peer_last_write_.tv_usec = 0;
222 
223  bodyBytesRead = -1;
224 }
225 
226 void
228 {
230 }
231 
232 void
234 {
236 }
237 
238 bool
239 HierarchyLogEntry::peerResponseTime(struct timeval &responseTime)
240 {
241  // no I/O whatsoever
242  if (peer_last_write_.tv_sec <= 0 && peer_last_read_.tv_sec <= 0)
243  return false;
244 
245  // accommodate read without (completed) write
246  const auto last_write = peer_last_write_.tv_sec > 0 ?
248 
249  // accommodate write without (completed) read
250  const auto last_read = peer_last_read_.tv_sec > 0 ?
252 
253  tvSub(responseTime, last_write, last_read);
254  // The peer response time (%<pt) stopwatch is currently defined to start
255  // when we wrote the entire request. Thus, if we wrote something after the
256  // last read, report zero peer response time.
257  if (responseTime.tv_sec < 0) {
258  responseTime.tv_sec = 0;
259  responseTime.tv_usec = 0;
260  }
261 
262  return true;
263 }
264 
265 static void
267 {
268 #if USE_FORW_VIA_DB
269  fvdbRegisterWithCacheManager();
270 #endif
271 }
272 
273 void
275 {
276  CustomLog *log;
277 
279 
280 #if USE_ADAPTATION
282 #endif
283 #if ICAP_CLIENT
285 #endif
286 
287  for (log = Config.Log.accesslogs; log; log = log->next) {
288  if (log->type == Log::Format::CLF_NONE)
289  continue;
290 
291  log->logfile = logfileOpen(log->filename, log->bufferSize, log->fatal);
292 
294 
295 #if USE_ADAPTATION
296  for (Format::Token * curr_token = (log->logFormat?log->logFormat->format:nullptr); curr_token; curr_token = curr_token->next) {
297  if (curr_token->type == Format::LFT_ADAPTATION_SUM_XACT_TIMES ||
298  curr_token->type == Format::LFT_ADAPTATION_ALL_XACT_TIMES ||
299  curr_token->type == Format::LFT_ADAPTATION_LAST_HEADER ||
300  curr_token->type == Format::LFT_ADAPTATION_LAST_HEADER_ELEM ||
301  curr_token->type == Format::LFT_ADAPTATION_LAST_ALL_HEADERS||
302  (curr_token->type == Format::LFT_NOTE && !Adaptation::Config::metaHeaders().empty())) {
304  }
305 #if ICAP_CLIENT
306  if (curr_token->type == Format::LFT_ICAP_TOTAL_TIME) {
308  }
309 #endif
310  }
311 #endif
312  }
313 }
314 
315 #if USE_FORW_VIA_DB
316 
317 static void
318 fvdbRegisterWithCacheManager(void)
319 {
320  Mgr::RegisterAction("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1);
321  Mgr::RegisterAction("forw_headers", "X-Forwarded-For Request Headers",
322  fvdbDumpForwarded, 0, 1);
323 }
324 
325 void
326 fvdbCountVia(const SBuf &headerValue)
327 {
328  ++TheViaCounts[headerValue];
329 }
330 
331 void
332 fvdbCountForwarded(const SBuf &key)
333 {
334  ++TheForwardedCounts[key];
335 }
336 
337 static void
338 fvdbDumpCounts(StoreEntry &e, const HeaderValueCounts &counts)
339 {
340  PackableStream os(e);
341  for (const auto &i : counts)
342  os << std::setw(9) << i.second << ' ' << i.first << "\n";
343 }
344 
345 static void
346 fvdbDumpVia(StoreEntry * e)
347 {
348  assert(e);
349  fvdbDumpCounts(*e, TheViaCounts);
350 }
351 
352 static void
353 fvdbDumpForwarded(StoreEntry * e)
354 {
355  assert(e);
356  fvdbDumpCounts(*e, TheForwardedCounts);
357 }
358 
359 static void
360 fvdbClear(void)
361 {
362  TheViaCounts.clear();
363  TheForwardedCounts.clear();
364 }
365 
366 #endif
367 
void accessLogLogTo(CustomLog *log, const AccessLogEntryPointer &al, ACLChecklist *checklist)
Definition: access_log.cc:66
Token * next
Definition: Token.h:73
hier_code peerType
Definition: Connection.h:152
struct timeval peer_last_write_
time of the last write to the last peer
void HttpdCombined(const AccessLogEntryPointer &al, Logfile *logfile)
Log with Apache httpd combined format.
@ LOOKUP_NONE
Definition: lookup_t.h:13
@ LFT_ADAPTATION_LAST_ALL_HEADERS
Definition: ByteCode.h:190
void SquidIcap(const AccessLogEntryPointer &al, Logfile *logfile)
Display log details in Squid ICAP format.
void logfileClose(Logfile *lf)
Definition: File.cc:92
@ CLF_COMMON
Definition: Formats.h:29
@ LFT_ADAPTATION_LAST_HEADER
Definition: ByteCode.h:188
@ scNone
Definition: StatusCode.h:21
static void accessLogRegisterWithCacheManager(void)
Definition: access_log.cc:266
void log(char *format,...)
bool isEmpty() const
Definition: SBuf.h:435
@ CLF_COMBINED
Definition: Formats.h:28
Definition: SBuf.h:93
#define LOG_DISABLE
Definition: defines.h:61
void accessLogClose(void)
Definition: access_log.cc:159
CustomLog * accesslogs
Definition: SquidConfig.h:186
LogConfig TheConfig
Definition: Config.cc:15
#define LOG_ENABLE
Definition: defines.h:60
HierarchyLogEntry hier
void HttpdCommon(const AccessLogEntryPointer &al, Logfile *logfile)
Log with Apache httpd common format.
int LogfileStatus
Definition: access_log.cc:63
char * xstrncpy(char *dst, const char *src, size_t n)
Definition: xstring.cc:37
Definition: forward.h:17
@ CLF_CUSTOM
Definition: Formats.h:30
void accessLogLog(const AccessLogEntryPointer &al, ACLChecklist *checklist)
Definition: access_log.cc:136
@ LFT_ICAP_TOTAL_TIME
Definition: ByteCode.h:195
char * name
Definition: CachePeer.h:61
class AccessLogEntry::HttpDetails http
void fvdbCountVia(const SBuf &)
bool empty() const
Definition: Notes.h:144
@ LFT_ADAPTATION_LAST_HEADER_ELEM
Definition: ByteCode.h:189
void clearPeerNotes()
forget previous notePeerRead() and notePeerWrite() calls (if any)
Definition: access_log.cc:215
@ CLF_ICAP_SQUID
Definition: Formats.h:32
bool hasIcapToken
Definition: Config.h:54
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:18
@ CLF_SQUID
Definition: Formats.h:35
char cd_host[SQUIDHOSTNAMELEN]
struct timeval store_complete_stop
void OBJH(StoreEntry *)
Definition: forward.h:44
static Notes & metaHeaders()
The list of configured meta headers.
Definition: Config.cc:35
@ CLF_REFERER
Definition: Formats.h:34
@ LFT_ADAPTATION_ALL_XACT_TIMES
Definition: ByteCode.h:187
struct timeval peer_select_start
@ HIER_NONE
Definition: hier_code.h:13
void logfileLineStart(Logfile *lf)
Definition: File.cc:126
const Acl::Answer & fastCheck()
Definition: Checklist.cc:298
void SquidNative(const AccessLogEntryPointer &al, Logfile *logfile)
Native Squid Format Display.
CachePeer * getPeer() const
Definition: Connection.cc:121
bool hasAdaptToken
Definition: Config.h:50
struct timeval peer_last_read_
time of the last read from the last peer
bool peerResponseTime(struct timeval &responseTime)
Definition: access_log.cc:239
Logfile * logfileOpen(const char *path, size_t bufsz, int fatal_flag)
Definition: File.cc:40
const char * dash_str
#define assert(EX)
Definition: assert.h:17
void fatalf(const char *fmt,...)
Definition: fatal.cc:68
@ LFT_ADAPTATION_SUM_XACT_TIMES
Definition: ByteCode.h:186
int code
Definition: smb-errors.c:145
@ CLF_USERAGENT
Definition: Formats.h:36
int64_t bodyBytesRead
number of body bytes received from the next hop or -1
Comm::ConnectionPointer tcpServer
TCP/IP level details of the last peer/server connection.
void fvdbCountForwarded(const SBuf &)
count occurrences of the given X-Forwarded-For header value
bool allowed() const
Definition: Acl.h:82
void SquidCustom(const AccessLogEntryPointer &al, CustomLog *log)
Log with a local custom format.
struct SquidConfig::@89 Log
void SquidReferer(const AccessLogEntryPointer &al, Logfile *logfile)
Display log details in Squid old refererlog format.
static char server[MAXLINE]
static StoreRebuildData counts
STL Allocator that uses Squid memory pools for memory management.
void RegisterAction(char const *action, char const *desc, OBJH *handler, Protected, Atomic, Format)
Definition: Registration.cc:54
void resetPeerNotes(const Comm::ConnectionPointer &server, const char *requestedHost)
Definition: access_log.cc:193
char host[SQUIDHOSTNAMELEN]
void logfileLineEnd(Logfile *lf)
Definition: File.cc:132
@ LFT_NOTE
Definition: ByteCode.h:239
void accessLogInit(void)
Definition: access_log.cc:274
@ CLF_NONE
Definition: Formats.h:37
void accessLogRotate(void)
Definition: access_log.cc:145
const SBuf Dash
#define SQUIDHOSTNAMELEN
Definition: rfc2181.h:30
void tvSub(struct timeval &res, struct timeval const &t1, struct timeval const &t2)
Definition: gadgets.cc:58
class SquidConfig Config
Definition: SquidConfig.cc:12
void SquidUserAgent(const AccessLogEntryPointer &al, Logfile *logfile)
Display log details in useragent format.

 

Introduction

Documentation

Support

Miscellaneous