• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

LogBuffer.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
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   LogEntryHeader
00047 
00048   This struct is automatically laid down at the head of each entry in the
00049   buffer.
00050   -------------------------------------------------------------------------*/
00051 
00052 struct LogEntryHeader
00053 {
00054   int64_t timestamp;               // the seconds portion of the timestamp
00055   int32_t timestamp_usec;          // the microseconds portion of the timestamp
00056   uint32_t entry_len;
00057 };
00058 
00059 /*-------------------------------------------------------------------------
00060   LogBufferHeader
00061 
00062   This struct is automatically laid down at the head of each buffer.
00063   -------------------------------------------------------------------------*/
00064 
00065 struct LogBufferHeader
00066 {
00067   uint32_t cookie;              // so we can find it on disk
00068   uint32_t version;             // in case we want to change it later
00069   uint32_t format_type;         // SQUID_LOG, COMMON_LOG, ...
00070   uint32_t byte_count;          // acutal # of bytes for the segment
00071   uint32_t entry_count;         // actual number of entries stored
00072   uint32_t low_timestamp;       // lowest timestamp value of entries
00073   uint32_t high_timestamp;      // highest timestamp value of entries
00074   uint32_t log_object_flags;        // log object flags
00075   uint64_t log_object_signature;  // log object signature
00076 #if defined(LOG_BUFFER_TRACKING)
00077   uint32_t int id;
00078 #endif                          // defined(LOG_BUFFER_TRACKING)
00079 
00080   // all offsets are computed from the start of the buffer (ie, "this"),
00081   // and so any valid offset will be at least sizeof(LogBufferHeader).
00082 
00083   uint32_t fmt_name_offset;     // offset to format name string
00084   uint32_t fmt_fieldlist_offset;        // offset to format fieldlist string
00085   uint32_t fmt_printf_offset;   // offset to format printf string
00086   uint32_t src_hostname_offset; // offset to source (client) hostname
00087   uint32_t log_filename_offset; // offset to log filename
00088   uint32_t data_offset;         // offset to start of data entry
00089   // section
00090 
00091   // some helper functions to return the header strings
00092 
00093   char *fmt_name();             // not used
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;              // buffer offset(bytes in buffer)
00122     uint16_t num_entries;         // number of entries in buffer
00123     uint16_t full:1;              // not accepting more checkouts
00124     uint16_t num_writers:15;      // number of writers
00125   } s;
00126 };
00127 
00128 /*-------------------------------------------------------------------------
00129   LogBuffer
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   // this should only be called when buffer is ready to be flushed
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   // static variables
00179   static vint32 M_ID;
00180 
00181   // static functions
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     // ink_atomic_increment() returns the previous value, so when it was 1, we are
00194     // the thread that decremented to zero and should delete ...
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;     // the unaligned buffer
00206   char *m_buffer;               // the buffer
00207   size_t m_size;                // the buffer size
00208   size_t m_buf_align;           // the buffer alignment
00209   size_t m_write_align;         // the write alignment mask
00210 
00211   long m_expiration_time;       // buffer expiration time
00212 
00213   LogObject *m_owner;           // the LogObject that owns this buf.
00214   LogBufferHeader *m_header;
00215 
00216   uint32_t m_id;                // unique buffer id (for debugging)
00217 public:
00218   volatile LB_State m_state;    // buffer state
00219   volatile int m_references;    // oustanding checkout_write references.
00220 private:
00221 
00222   // private functions
00223   size_t _add_buffer_header();
00224   unsigned add_header_str(const char *str, char *buf_ptr, unsigned buf_len);
00225 
00226   // -- member functions that are not allowed --
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   LogBufferList
00238 
00239   Support atomic operations on a list of LogBuffer objects.
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   LogBufferIterator
00263 
00264   This class will iterate over the entries in a LogBuffer.
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   // -- member functions not allowed --
00281     LogBufferIterator();
00282     LogBufferIterator(const LogBufferIterator &);
00283     LogBufferIterator & operator=(const LogBufferIterator &);
00284 };
00285 
00286 
00287 /*-------------------------------------------------------------------------
00288   LogBufferIterator
00289 
00290   This class provides the ability to iterate over the LogEntries stored
00291   within a given LogBuffer.
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

Generated by  doxygen 1.7.1