Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef LOG_BUFFER_H
00026 #define LOG_BUFFER_H
00027
00028 #include "libts.h"
00029 #include "LogFormat.h"
00030 #include "LogLimits.h"
00031 #include "LogAccess.h"
00032
00033 class LogObject;
00034 class LogBufferIterator;
00035
00036 #define LOG_SEGMENT_COOKIE 0xaceface
00037 #define LOG_SEGMENT_VERSION 2
00038
00039 #if defined(linux)
00040 #define LB_DEFAULT_ALIGN 512
00041 #else
00042 #define LB_DEFAULT_ALIGN 8
00043 #endif
00044
00045
00046
00047
00048
00049
00050
00051
00052 struct LogEntryHeader
00053 {
00054 int64_t timestamp;
00055 int32_t timestamp_usec;
00056 uint32_t entry_len;
00057 };
00058
00059
00060
00061
00062
00063
00064
00065 struct LogBufferHeader
00066 {
00067 uint32_t cookie;
00068 uint32_t version;
00069 uint32_t format_type;
00070 uint32_t byte_count;
00071 uint32_t entry_count;
00072 uint32_t low_timestamp;
00073 uint32_t high_timestamp;
00074 uint32_t log_object_flags;
00075 uint64_t log_object_signature;
00076 #if defined(LOG_BUFFER_TRACKING)
00077 uint32_t int id;
00078 #endif // defined(LOG_BUFFER_TRACKING)
00079
00080
00081
00082
00083 uint32_t fmt_name_offset;
00084 uint32_t fmt_fieldlist_offset;
00085 uint32_t fmt_printf_offset;
00086 uint32_t src_hostname_offset;
00087 uint32_t log_filename_offset;
00088 uint32_t data_offset;
00089
00090
00091
00092
00093 char *fmt_name();
00094 char *fmt_fieldlist();
00095 char *fmt_printf();
00096 char *src_hostname();
00097 char *log_filename();
00098 };
00099
00100
00101 union LB_State
00102 {
00103 LB_State()
00104 : ival(0)
00105 { }
00106
00107 LB_State(volatile LB_State & vs)
00108 {
00109 ival = vs.ival;
00110 }
00111
00112 LB_State & operator =(volatile LB_State & vs)
00113 {
00114 ival = vs.ival;
00115 return *this;
00116 }
00117
00118 int64_t ival;
00119 struct
00120 {
00121 uint32_t offset;
00122 uint16_t num_entries;
00123 uint16_t full:1;
00124 uint16_t num_writers:15;
00125 } s;
00126 };
00127
00128
00129
00130
00131 class LogBuffer
00132 {
00133 public:
00134 SLINK(LogBuffer, write_link);
00135 enum LB_ResultCode {
00136 LB_OK = 0,
00137 LB_FULL_NO_WRITERS,
00138 LB_FULL_ACTIVE_WRITERS,
00139 LB_RETRY,
00140 LB_ALL_WRITERS_DONE,
00141 LB_BUSY,
00142 LB_BUFFER_TOO_SMALL
00143 };
00144
00145 LogBuffer(LogObject * owner, size_t size,
00146 size_t buf_align = LB_DEFAULT_ALIGN, size_t write_align = INK_MIN_ALIGN);
00147 LogBuffer(LogObject * owner, LogBufferHeader * header);
00148 ~LogBuffer();
00149
00150 char &operator [] (int idx)
00151 {
00152 ink_assert(idx >= 0);
00153 ink_assert((size_t) idx < m_size);
00154 return m_buffer[idx];
00155 }
00156
00157 int switch_state(LB_State & old_state, LB_State & new_state)
00158 {
00159 INK_WRITE_MEMORY_BARRIER;
00160 return (ink_atomic_cas( & m_state.ival, old_state.ival, new_state.ival));
00161 }
00162
00163 LB_ResultCode checkout_write(size_t * write_offset, size_t write_size);
00164 LB_ResultCode checkin_write(size_t write_offset);
00165 void force_full();
00166
00167 LogBufferHeader *header() { return m_header; }
00168 long expiration_time() { return m_expiration_time; }
00169
00170
00171 void update_header_data();
00172
00173 uint32_t get_id() { return m_id; }
00174 LogObject *get_owner() const { return m_owner; }
00175
00176 LINK(LogBuffer, link);;
00177
00178
00179 static vint32 M_ID;
00180
00181
00182 static size_t max_entry_bytes();
00183 static int to_ascii(LogEntryHeader * entry, LogFormatType type,
00184 char *buf, int max_len, const char *symbol_str, char *printf_str,
00185 unsigned buffer_version, const char *alt_format = NULL);
00186 static int resolve_custom_entry(LogFieldList * fieldlist,
00187 char *printf_str, char *read_from, char *write_to,
00188 int write_to_len, long timestamp, long timestamp_us,
00189 unsigned buffer_version, LogFieldList * alt_fieldlist = NULL,
00190 char *alt_printf_str = NULL);
00191
00192 static void destroy(LogBuffer *lb) {
00193
00194
00195 int refcnt = ink_atomic_increment(&lb->m_references, -1);
00196
00197 if (refcnt == 1) {
00198 delete lb;
00199 }
00200
00201 ink_release_assert(refcnt >= 0);
00202 }
00203
00204 private:
00205 char *m_unaligned_buffer;
00206 char *m_buffer;
00207 size_t m_size;
00208 size_t m_buf_align;
00209 size_t m_write_align;
00210
00211 long m_expiration_time;
00212
00213 LogObject *m_owner;
00214 LogBufferHeader *m_header;
00215
00216 uint32_t m_id;
00217 public:
00218 volatile LB_State m_state;
00219 volatile int m_references;
00220 private:
00221
00222
00223 size_t _add_buffer_header();
00224 unsigned add_header_str(const char *str, char *buf_ptr, unsigned buf_len);
00225
00226
00227 LogBuffer();
00228 LogBuffer(const LogBuffer & rhs);
00229 LogBuffer & operator=(const LogBuffer & rhs);
00230
00231 friend class LogBufferIterator;
00232 };
00233
00234 class LogFile;
00235
00236
00237
00238
00239
00240
00241
00242 class LogBufferList
00243 {
00244 private:
00245 Queue<LogBuffer> m_buffer_list;
00246 ink_mutex m_mutex;
00247 int m_size;
00248
00249 public:
00250 LogBufferList();
00251 ~LogBufferList();
00252
00253 void add(LogBuffer * lb);
00254 LogBuffer *get(void);
00255 int get_size(void)
00256 {
00257 return m_size;
00258 }
00259 };
00260
00261
00262
00263
00264
00265
00266
00267 class LogBufferIterator {
00268 public:
00269 LogBufferIterator(LogBufferHeader * header, bool in_network_order = false);
00270 ~LogBufferIterator();
00271
00272 LogEntryHeader *next();
00273
00274 private:
00275 bool m_in_network_order;
00276 char *m_next;
00277 unsigned m_iter_entry_count;
00278 unsigned m_buffer_entry_count;
00279
00280
00281 LogBufferIterator();
00282 LogBufferIterator(const LogBufferIterator &);
00283 LogBufferIterator & operator=(const LogBufferIterator &);
00284 };
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 inline
00295 LogBufferIterator::LogBufferIterator(LogBufferHeader * header, bool in_network_order)
00296 : m_in_network_order(in_network_order),
00297 m_next(0),
00298 m_iter_entry_count(0),
00299 m_buffer_entry_count(0)
00300 {
00301 ink_assert(header);
00302
00303 switch (header->version) {
00304 case LOG_SEGMENT_VERSION:
00305 m_next = (char *) header + header->data_offset;
00306 m_buffer_entry_count = header->entry_count;
00307 break;
00308
00309 default:
00310 Note("Invalid LogBuffer version %d in LogBufferIterator; "
00311 "current version is %d", header->version, LOG_SEGMENT_VERSION);
00312 break;
00313 }
00314 }
00315
00316
00317
00318
00319
00320 inline
00321 LogBufferIterator::~LogBufferIterator()
00322 {
00323 }
00324 #endif