~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to proxy/logging/LogBuffer.h

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
  A brief file description
 
4
 
 
5
  @section license License
 
6
 
 
7
  Licensed to the Apache Software Foundation (ASF) under one
 
8
  or more contributor license agreements.  See the NOTICE file
 
9
  distributed with this work for additional information
 
10
  regarding copyright ownership.  The ASF licenses this file
 
11
  to you under the Apache License, Version 2.0 (the
 
12
  "License"); you may not use this file except in compliance
 
13
  with the License.  You may obtain a copy of the License at
 
14
 
 
15
      http://www.apache.org/licenses/LICENSE-2.0
 
16
 
 
17
  Unless required by applicable law or agreed to in writing, software
 
18
  distributed under the License is distributed on an "AS IS" BASIS,
 
19
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
20
  See the License for the specific language governing permissions and
 
21
  limitations under the License.
 
22
 */
 
23
 
 
24
 
 
25
#if !defined (INK_NO_LOG)
 
26
#ifndef LOG_BUFFER_H
 
27
#define LOG_BUFFER_H
 
28
 
 
29
#include "libts.h"
 
30
#include "LogFormatType.h"
 
31
#include "LogLimits.h"
 
32
 
 
33
#include "LogBufferV1.h"
 
34
#include "LogAccess.h"
 
35
 
 
36
class LogObject;
 
37
class LogBufferIterator;
 
38
 
 
39
#define LOG_SEGMENT_COOKIE 0xaceface
 
40
#define LOG_SEGMENT_VERSION 2
 
41
 
 
42
#if defined(linux)
 
43
#define LB_DEFAULT_ALIGN 512
 
44
#else
 
45
#define LB_DEFAULT_ALIGN 8
 
46
#endif
 
47
 
 
48
/*-------------------------------------------------------------------------
 
49
  LogEntryHeader
 
50
 
 
51
  This struct is automatically laid down at the head of each entry in the
 
52
  buffer.
 
53
  -------------------------------------------------------------------------*/
 
54
 
 
55
struct LogEntryHeader
 
56
{
 
57
//    unsigned timestamp;
 
58
  long timestamp;               // the seconds portion of the timestamp
 
59
  long timestamp_usec;          // the microseconds portion of the timestamp
 
60
  unsigned entry_len;
 
61
};
 
62
 
 
63
/*-------------------------------------------------------------------------
 
64
  LogBufferHeader
 
65
 
 
66
  This struct is automatically laid down at the head of each buffer.
 
67
  -------------------------------------------------------------------------*/
 
68
 
 
69
struct LogBufferHeader
 
70
{
 
71
 
 
72
  unsigned cookie;              // so we can find it on disk
 
73
  unsigned version;             // in case we want to change it later
 
74
  unsigned format_type;         // SQUID_LOG, COMMON_LOG, ...
 
75
  unsigned byte_count;          // acutal # of bytes for the segment
 
76
  unsigned entry_count;         // actual number of entries stored
 
77
  unsigned low_timestamp;       // lowest timestamp value of entries
 
78
  unsigned high_timestamp;      // highest timestamp value of entries
 
79
  unsigned int log_object_flags;        // log object flags
 
80
  uint64_t log_object_signature;  // log object signature
 
81
#if defined(LOG_BUFFER_TRACKING)
 
82
  unsigned int id;
 
83
#endif                          // defined(LOG_BUFFER_TRACKING)
 
84
 
 
85
  // all offsets are computed from the start of the buffer (ie, "this"),
 
86
  // and so any valid offset will be at least sizeof(LogBufferHeader).
 
87
 
 
88
  unsigned fmt_name_offset;     // offset to format name string
 
89
  unsigned fmt_fieldlist_offset;        // offset to format fieldlist string
 
90
  unsigned fmt_printf_offset;   // offset to format printf string
 
91
  unsigned src_hostname_offset; // offset to source (client) hostname
 
92
  unsigned log_filename_offset; // offset to log filename
 
93
  unsigned data_offset;         // offset to start of data entry
 
94
  // section
 
95
 
 
96
  // some helper functions to return the header strings
 
97
 
 
98
  char *fmt_name();             // not used
 
99
  char *fmt_fieldlist();
 
100
  char *fmt_printf();
 
101
  char *src_hostname();
 
102
  char *log_filename();
 
103
};
 
104
 
 
105
 
 
106
union LB_State
 
107
{
 
108
  LB_State():ival(0)
 
109
  {
 
110
  };
 
111
 
 
112
  LB_State(volatile LB_State & vs)
 
113
  {
 
114
    ival = vs.ival;
 
115
  };
 
116
 
 
117
  LB_State & operator =(volatile LB_State & vs)
 
118
  {
 
119
    ival = vs.ival;
 
120
    return *this;
 
121
  }
 
122
 
 
123
  uint64_t ival;
 
124
  struct
 
125
  {
 
126
    uint16_t offset;              // buffer should be <= 64KB
 
127
    uint16_t num_entries;         // number of entries in buffer
 
128
    uint16_t byte_count;          // bytes in buffer
 
129
    uint16_t full:1;              // not accepting more checkouts
 
130
    uint16_t num_writers:15;      // number of writers
 
131
  } s;
 
132
};
 
133
 
 
134
 
 
135
/* ---------------------------------- iObject ------------------------------ */
 
136
class iObjectActivator;
 
137
class iObject
 
138
{
 
139
private:
 
140
  static iObject *free_heap;    /* list of free blocks */
 
141
  static ink_mutex iObjectMutex;        /* mutex for access to iObject class global variables */
 
142
 
 
143
  size_t class_size;            /* real class size */
 
144
  iObject *next_object;
 
145
 
 
146
 
 
147
protected:
 
148
  iObject(const iObject &);   /* declared; not implemented - block copying and assignment */
 
149
  iObject & operator=(const iObject &);       /* ditto */
 
150
 
 
151
public:
 
152
  static void Init(void);
 
153
  void *operator  new(size_t size);
 
154
  void operator  delete(void *p);
 
155
 
 
156
 iObject()
 
157
 {                             /* nop */
 
158
 }
 
159
 
 
160
 virtual ~iObject()
 
161
 {                             /* nop */
 
162
 }
 
163
 
 
164
 friend class iObjectActivator;
 
165
};
 
166
 
 
167
/* ------------------------------ iLogBufferBuffer ------------------------- */
 
168
class iLogBufferBuffer
 
169
{
 
170
private:
 
171
  static iLogBufferBuffer *free_heap;   /* list of free blocks */
 
172
  static ink_mutex iLogBufferBufferMutex;       /* mutex for access iLogBufferBuffer class global variables */
 
173
 
 
174
  iLogBufferBuffer *next;
 
175
  size_t real_buf_size;
 
176
 
 
177
 
 
178
  iLogBufferBuffer()
 
179
  {
 
180
    next = 0;
 
181
    buf = 0;
 
182
    real_buf_size = (size = 0);
 
183
  }
 
184
 
 
185
  ~iLogBufferBuffer()
 
186
  {
 
187
    if (buf)
 
188
      xfree(buf);
 
189
    real_buf_size = (size = 0);
 
190
  }
 
191
 
 
192
protected:
 
193
  iLogBufferBuffer(const iLogBufferBuffer &);   /* declared; not implemented - block copying and assignment */
 
194
  iLogBufferBuffer & operator=(const iLogBufferBuffer &);       /* ditto */
 
195
 
 
196
public:
 
197
  char *buf;
 
198
  size_t size;
 
199
 
 
200
  static void Init(void);
 
201
  static iLogBufferBuffer *New_iLogBufferBuffer(size_t _buf_size);
 
202
  static iLogBufferBuffer *Delete_iLogBufferBuffer(iLogBufferBuffer * _b);
 
203
 
 
204
  friend class iObjectActivator;
 
205
};
 
206
 
 
207
/* ---------------------------- iObjectActivator --------------------------- */
 
208
class iObjectActivator
 
209
{
 
210
public:
 
211
  iObjectActivator()
 
212
  {
 
213
    iObject::Init();
 
214
    iLogBufferBuffer::Init();
 
215
  }
 
216
 
 
217
  ~iObjectActivator()
 
218
  {                             /* nop */
 
219
  }
 
220
};
 
221
 
 
222
/*-------------------------------------------------------------------------
 
223
  LogBuffer
 
224
  -------------------------------------------------------------------------*/
 
225
#define CLASS_SIGN_LOGBUFFER 0xFACE5370 /* LogBuffer class signature */
 
226
 
 
227
class LogBuffer:public iObject
 
228
{
 
229
public:
 
230
  unsigned long sign;           /* class signature (must be CLASS_SIGN_LOGBUFFER) */
 
231
  LogBuffer *next_flush;        /* next in flush list */
 
232
  LogBuffer *next_list;         /* next in list */
 
233
 
 
234
  enum LB_ResultCode
 
235
  {
 
236
    LB_OK = 0,
 
237
    LB_FULL_NO_WRITERS,
 
238
    LB_FULL_ACTIVE_WRITERS,
 
239
    LB_RETRY,
 
240
    LB_ALL_WRITERS_DONE,
 
241
    LB_BUSY,
 
242
    LB_BUFFER_TOO_SMALL
 
243
  };
 
244
 
 
245
    LogBuffer(LogObject * owner, size_t size,
 
246
              size_t buf_align = LB_DEFAULT_ALIGN, size_t write_align = INK_MIN_ALIGN);
 
247
    LogBuffer(LogObject * owner, LogBufferHeader * header);
 
248
   ~LogBuffer();
 
249
  char &operator [] (int idx)
 
250
  {
 
251
    ink_debug_assert(idx >= 0);
 
252
    ink_debug_assert((size_t) idx < m_size);
 
253
    return m_buffer[idx];
 
254
  };
 
255
 
 
256
  int switch_state(LB_State & old_state, LB_State & new_state)
 
257
  {
 
258
    INK_WRITE_MEMORY_BARRIER;
 
259
    return (ink_atomic_cas64((int64_t *) & m_state.ival, old_state.ival, new_state.ival));
 
260
  };
 
261
 
 
262
  LB_ResultCode checkout_write(size_t * write_offset, size_t write_size);
 
263
  LB_ResultCode checkin_write(size_t write_offset);
 
264
  void force_full();
 
265
 
 
266
  LogBufferHeader *header()
 
267
  {
 
268
    return m_header;
 
269
  }
 
270
  long expiration_time()
 
271
  {
 
272
    return m_expiration_time;
 
273
  }
 
274
 
 
275
  // this should only be called when buffer is ready to be flushed
 
276
  void update_header_data();
 
277
  void convert_to_network_order();
 
278
  void convert_to_host_order();
 
279
  uint32_t get_id()
 
280
  {
 
281
    return m_id;
 
282
  };
 
283
  LogObject *get_owner() const
 
284
  {
 
285
    return m_owner;
 
286
  };
 
287
 
 
288
  Link<LogBuffer> link;
 
289
 
 
290
  // static variables
 
291
  static vint32 M_ID;
 
292
 
 
293
  // static functions
 
294
  static size_t max_entry_bytes();
 
295
  static int to_ascii(LogEntryHeader * entry, LogFormatType type,
 
296
                      char *buf, int max_len, char *symbol_str, char *printf_str,
 
297
                      unsigned buffer_version, char *alt_format = NULL);
 
298
  static int resolve_custom_entry(LogFieldList * fieldlist,
 
299
                                  char *printf_str, char *read_from, char *write_to,
 
300
                                  int write_to_len, long timestamp, long timestamp_us,
 
301
                                  unsigned buffer_version, LogFieldList * alt_fieldlist = NULL,
 
302
                                  char *alt_printf_str = NULL);
 
303
  static void convert_to_network_order(LogBufferHeader * header);
 
304
  static void convert_to_host_order(LogBufferHeader * header);
 
305
 
 
306
private:
 
307
  iLogBufferBuffer * m_bb;      // real buffer
 
308
  char *m_new_buffer;           // new buffer (must be free)
 
309
  char *m_unaligned_buffer;     // the unaligned buffer
 
310
  char *m_buffer;               // the buffer
 
311
  size_t m_size;                // the buffer size
 
312
  size_t m_buf_align;           // the buffer alignment
 
313
  size_t m_write_align;         // the write alignment mask
 
314
 
 
315
  volatile LB_State m_state;    // buffer state
 
316
 
 
317
  int m_max_entries;            // max number of entries allowed
 
318
  long m_expiration_time;       // buffer expiration time
 
319
 
 
320
  LogObject *m_owner;           // the LogObject that owns this buf.
 
321
  LogBufferHeader *m_header;
 
322
 
 
323
  uint32_t m_id;                  // unique buffer id (for debugging)
 
324
 
 
325
  // private functions
 
326
  size_t _add_buffer_header();
 
327
  unsigned add_header_str(char *str, char *buf_ptr, unsigned buf_len);
 
328
 
 
329
  // -- member functions that are not allowed --
 
330
  LogBuffer();
 
331
  LogBuffer(const LogBuffer & rhs);
 
332
  LogBuffer & operator=(const LogBuffer & rhs);
 
333
 
 
334
  friend class LogBufferIterator;
 
335
};
 
336
 
 
337
class LogFile;
 
338
 
 
339
/*-------------------------------------------------------------------------
 
340
  LogBufferList
 
341
 
 
342
  Support atomic operations on a list of LogBuffer objects.
 
343
  -------------------------------------------------------------------------*/
 
344
 
 
345
class LogBufferList
 
346
{
 
347
private:
 
348
  LogBuffer * m_list;
 
349
  LogBuffer *m_list_last_ptr;
 
350
  ink_mutex m_mutex;
 
351
  int m_size;
 
352
 
 
353
public:
 
354
    LogBufferList();
 
355
   ~LogBufferList();
 
356
 
 
357
  void add(LogBuffer * lb);
 
358
  LogBuffer *get(void);
 
359
  int get_size(void)
 
360
  {
 
361
    return m_size;
 
362
  }
 
363
};
 
364
 
 
365
/*-------------------------------------------------------------------------
 
366
  LogBufferIterator
 
367
 
 
368
  This class will iterate over the entries in a LogBuffer.
 
369
  -------------------------------------------------------------------------*/
 
370
 
 
371
class LogBufferIterator
 
372
{
 
373
public:
 
374
  LogBufferIterator(LogBufferHeader * header, bool in_network_order = false);
 
375
  ~LogBufferIterator();
 
376
 
 
377
  LogEntryHeader *next();
 
378
 
 
379
private:
 
380
  bool m_in_network_order;
 
381
  char *m_next;
 
382
  unsigned m_iter_entry_count;
 
383
  unsigned m_buffer_entry_count;
 
384
 
 
385
  // -- member functions not allowed --
 
386
    LogBufferIterator();
 
387
    LogBufferIterator(const LogBufferIterator &);
 
388
    LogBufferIterator & operator=(const LogBufferIterator &);
 
389
};
 
390
 
 
391
 
 
392
/*-------------------------------------------------------------------------
 
393
  LogBufferIterator
 
394
 
 
395
  This class provides the ability to iterate over the LogEntries stored
 
396
  within a given LogBuffer.
 
397
  -------------------------------------------------------------------------*/
 
398
 
 
399
inline
 
400
LogBufferIterator::LogBufferIterator(LogBufferHeader * header, bool in_network_order)
 
401
                  : m_in_network_order(in_network_order),
 
402
                  m_next(0),
 
403
                  m_iter_entry_count(0),
 
404
                  m_buffer_entry_count(0)
 
405
{
 
406
  ink_debug_assert(header);
 
407
 
 
408
  switch (header->version) {
 
409
  case LOG_SEGMENT_VERSION:
 
410
    m_next = (char *) header + header->data_offset;
 
411
    m_buffer_entry_count = header->entry_count;
 
412
    break;
 
413
 
 
414
  case 1:
 
415
    m_next = (char *) header + ((LogBufferHeaderV1 *) header)->data_offset;
 
416
    m_buffer_entry_count = ((LogBufferHeaderV1 *) header)->entry_count;
 
417
    break;
 
418
 
 
419
  default:
 
420
    Note("Invalid LogBuffer version %d in LogBufferIterator; "
 
421
         "current version is %d", header->version, LOG_SEGMENT_VERSION);
 
422
    break;
 
423
  }
 
424
}
 
425
 
 
426
 
 
427
/*-------------------------------------------------------------------------
 
428
  -------------------------------------------------------------------------*/
 
429
 
 
430
inline
 
431
LogBufferIterator::~
 
432
LogBufferIterator()
 
433
{
 
434
}
 
435
 
 
436
 
 
437
#endif
 
438
#endif //INK_NO_LOG