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 #pragma once
25 
26 #define LOG_FIELD_MARKER '\377'
27 
28 #include "tscore/ink_platform.h"
29 #include "LogField.h"
30 
31 enum LogFormatType {
32   // We start the numbering at 4 to compatibility with Traffic Server 4.x, which used
33   // to have the predefined log formats enumerated above ...
34   LOG_FORMAT_CUSTOM = 4,
35   LOG_FORMAT_TEXT   = 5
36 };
37 
38 enum LogFileFormat {
39   LOG_FILE_BINARY,
40   LOG_FILE_ASCII,
41   LOG_FILE_PIPE, // ie. ASCII pipe
42   N_LOGFILE_TYPES
43 };
44 
45 /*-------------------------------------------------------------------------
46   LogFormat
47 
48   Now, this object will simply store the characteristics of a log format,
49   which is defined as a set of fields.
50   -------------------------------------------------------------------------*/
51 
52 class LogFormat : public RefCountObj
53 {
54 public:
55   LogFormat(const char *name, const char *format_str, unsigned interval_sec = 0);
56   LogFormat(const char *name, const char *fieldlist_str, const char *printf_str, unsigned interval_sec = 0);
57   LogFormat(const LogFormat &rhs);
58 
59   ~LogFormat() override;
60 
61   void display(FILE *fd = stdout);
62 
63   bool
valid()64   valid() const
65   {
66     return m_valid;
67   }
68   char *
name()69   name() const
70   {
71     return m_name_str;
72   }
73   char *
fieldlist()74   fieldlist() const
75   {
76     return m_fieldlist_str;
77   }
78   char *
format_string()79   format_string() const
80   {
81     return m_format_str;
82   }
83   int32_t
name_id()84   name_id() const
85   {
86     return m_name_id;
87   }
88   unsigned
fieldlist_id()89   fieldlist_id() const
90   {
91     return m_fieldlist_id;
92   }
93   LogFormatType
type()94   type() const
95   {
96     return m_format_type;
97   }
98   char *
printf_str()99   printf_str() const
100   {
101     return m_printf_str;
102   }
103   bool
is_aggregate()104   is_aggregate() const
105   {
106     return m_aggregate;
107   }
108   unsigned
field_count()109   field_count() const
110   {
111     return m_field_count;
112   }
113   long
interval()114   interval() const
115   {
116     return m_interval_sec;
117   }
118 
119 public:
120   static int32_t id_from_name(const char *name);
121   static LogFormat *format_from_specification(char *spec, char **file_name, char **file_header, LogFileFormat *file_type);
122   static int parse_symbol_string(const char *symbol_string, LogFieldList *field_list, bool *contains_aggregates);
123   static int parse_format_string(const char *format_str, char **printf_str, char **fields_str);
124   static int parse_escape_string(const char *str, int len);
125 
126   // these are static because m_tagging_on is a class variable
127   static void
turn_tagging_on()128   turn_tagging_on()
129   {
130     m_tagging_on = true;
131   }
132   static void
turn_tagging_off()133   turn_tagging_off()
134   {
135     m_tagging_on = false;
136   }
137 
138 private:
139   bool setup(const char *name, const char *format_str, unsigned interval_sec = 0);
140   void init_variables(const char *name, const char *fieldlist_str, const char *printf_str, unsigned interval_sec);
141 
142 public:
143   LogFieldList m_field_list;
144   long m_interval_sec;
145   long m_interval_next;
146   char *m_agg_marshal_space;
147 
148 private:
149   static bool m_tagging_on; // flag to control tagging, class
150   // variable
151   bool m_valid;
152   char *m_name_str;
153   int32_t m_name_id;
154   char *m_fieldlist_str;
155   unsigned m_fieldlist_id;
156   unsigned m_field_count;
157   char *m_printf_str;
158   bool m_aggregate;
159   char *m_format_str;
160   LogFormatType m_format_type;
161 
162 public:
163   LINK(LogFormat, link);
164 
165   // noncopyable
166   LogFormat &operator=(LogFormat &rhs) = delete;
167 
168 private:
169   // -- member functions that are not allowed --
170   LogFormat();
171 };
172 
173 // For text logs, there is no format string; we'll simply log the
174 // entire entry as a string without any field substitutions.  To
175 // indicate this, the format_str will be NULL.
176 static inline LogFormat *
177 MakeTextLogFormat(const char *name = "text")
178 {
179   return new LogFormat(name, nullptr /* format_str */);
180 }
181 
182 /*-------------------------------------------------------------------------
183   LogFormatList
184   -------------------------------------------------------------------------*/
185 
186 class LogFormatList
187 {
188 public:
189   LogFormatList();
190   ~LogFormatList();
191 
192   void add(LogFormat *format, bool copy = true);
193   LogFormat *find_by_name(const char *name) const;
194 
195   LogFormat *
first()196   first() const
197   {
198     return m_format_list.head;
199   }
200   LogFormat *
next(LogFormat * here)201   next(LogFormat *here) const
202   {
203     return (here->link).next;
204   }
205 
206   void clear();
207   unsigned count();
208   void display(FILE *fd = stdout);
209 
210   // noncopyable
211   // -- member functions that are not allowed --
212   LogFormatList(const LogFormatList &rhs) = delete;
213   LogFormatList &operator=(const LogFormatList &rhs) = delete;
214 
215 private:
216   Queue<LogFormat> m_format_list;
217 };
218