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