~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to proxy/logging/LogFilter.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
#ifndef LOG_FILTER_H
 
26
#define LOG_FILTER_H
 
27
 
 
28
#include "libts.h"
 
29
#include "LogAccess.h"
 
30
#include "LogField.h"
 
31
#include "LogFormat.h"
 
32
 
 
33
/*-------------------------------------------------------------------------
 
34
  LogFilter
 
35
 
 
36
  This is an abstract base class from which particular filters can be
 
37
  derived.  Each filter must implement the "toss_this_entry" member
 
38
  function which, given a LogAccess object, returns true if
 
39
  the log entry is to be tossed out.
 
40
  -------------------------------------------------------------------------*/
 
41
 
 
42
class LogFilter
 
43
{
 
44
public:
 
45
 
 
46
  enum Type
 
47
  {
 
48
    INT_FILTER = 0,
 
49
    STRING_FILTER,
 
50
    N_TYPES
 
51
  };
 
52
 
 
53
  enum Action
 
54
  {
 
55
    REJECT = 0,
 
56
    ACCEPT,
 
57
    N_ACTIONS
 
58
  };
 
59
  static const char *ACTION_NAME[];
 
60
 
 
61
  // all operators "positive" (i.e., there is no NOMATCH operator anymore)
 
62
  // because one can specify through the "action" field if the record should
 
63
  // be kept or tossed away
 
64
  //
 
65
  enum Operator
 
66
  {
 
67
    MATCH = 0,
 
68
    CASE_INSENSITIVE_MATCH,
 
69
    CONTAIN,
 
70
    CASE_INSENSITIVE_CONTAIN,
 
71
    N_OPERATORS
 
72
  };
 
73
  static const char *OPERATOR_NAME[];
 
74
 
 
75
  LogFilter(const char *name, LogField * field, Action action, Operator oper);
 
76
  virtual ~ LogFilter();
 
77
 
 
78
  char *name() const { return m_name; }
 
79
  Type type() const { return m_type; }
 
80
  size_t get_num_values() const { return m_num_values; };
 
81
 
 
82
  virtual bool toss_this_entry(LogAccess * lad) = 0;
 
83
  virtual void display(FILE * fd = stdout) = 0;
 
84
  virtual void display_as_XML(FILE * fd = stdout) = 0;
 
85
 
 
86
  void reverse()
 
87
  {
 
88
    m_action = (m_action == REJECT ? ACCEPT : REJECT);
 
89
  };
 
90
 
 
91
protected:
 
92
  char *m_name;
 
93
  LogField *m_field;
 
94
  Action m_action;              // the action this filter takes
 
95
  Operator m_operator;
 
96
  Type m_type;
 
97
  size_t m_num_values;          // the number of comparison values
 
98
 
 
99
public:
 
100
  LINK(LogFilter, link);      // so we can create a LogFilterList
 
101
 
 
102
private:
 
103
  // -- member functions that are not allowed --
 
104
  LogFilter();
 
105
  LogFilter(const LogFilter & rhs);
 
106
  LogFilter & operator=(LogFilter & rhs);
 
107
};
 
108
 
 
109
/*-------------------------------------------------------------------------
 
110
  LogFilterString
 
111
 
 
112
  Filter for string fields.
 
113
  -------------------------------------------------------------------------*/
 
114
 
 
115
class LogFilterString:public LogFilter
 
116
{
 
117
public:
 
118
  LogFilterString(const char *name, LogField * field, Action a, Operator o, char *value);
 
119
  LogFilterString(const char *name, LogField * field, Action a, Operator o, size_t num_values, char **value);
 
120
  LogFilterString(const LogFilterString & rhs);
 
121
  ~LogFilterString();
 
122
  bool operator==(LogFilterString & rhs);
 
123
 
 
124
  bool toss_this_entry(LogAccess * lad);
 
125
  void display(FILE * fd = stdout);
 
126
  void display_as_XML(FILE * fd = stdout);
 
127
 
 
128
private:
 
129
  char **m_value;               // the array of values
 
130
 
 
131
  // these are used to speed up case insensitive operations
 
132
  //
 
133
  char **m_value_uppercase;     // m_value in all uppercase
 
134
  size_t *m_length;             // length of m_value string
 
135
 
 
136
  void _setValues(size_t n, char **value);
 
137
 
 
138
  // note: OperatorFunction's must return 0 (zero) if condition is satisfied
 
139
  // (as strcmp does)
 
140
  typedef int (*OperatorFunction) (const char *, const char *);
 
141
 
 
142
  static int _isSubstring(const char *s0, const char *s1)
 
143
  {
 
144
    // return 0 if s1 is substring of s0 and 1 otherwise
 
145
    // this reverse behavior is to conform to the behavior of strcmp
 
146
    // which returns 0 if strings match
 
147
    return (strstr(s0, s1) == NULL ? 1 : 0);
 
148
  };
 
149
 
 
150
  enum LengthCondition
 
151
  {
 
152
    DATA_LENGTH_EQUAL = 0,
 
153
    DATA_LENGTH_LARGER
 
154
  };
 
155
 
 
156
  inline bool _checkCondition(OperatorFunction f,
 
157
                              const char *field_value, size_t field_value_length, char **val, LengthCondition lc);
 
158
 
 
159
  // -- member functions that are not allowed --
 
160
  LogFilterString();
 
161
  LogFilterString & operator=(LogFilterString & rhs);
 
162
};
 
163
 
 
164
/*-------------------------------------------------------------------------
 
165
  LogFilterInt
 
166
 
 
167
  Filter for int fields.
 
168
  -------------------------------------------------------------------------*/
 
169
 
 
170
class LogFilterInt:public LogFilter
 
171
{
 
172
public:
 
173
  LogFilterInt(const char *name, LogField * field, Action a, Operator o, int64_t value);
 
174
    LogFilterInt(const char *name, LogField * field, Action a, Operator o, size_t num_values, int64_t *value);
 
175
    LogFilterInt(const char *name, LogField * field, Action a, Operator o, char *values);
 
176
    LogFilterInt(const LogFilterInt & rhs);
 
177
   ~LogFilterInt();
 
178
  bool operator==(LogFilterInt & rhs);
 
179
 
 
180
  bool toss_this_entry(LogAccess * lad);
 
181
  void display(FILE * fd = stdout);
 
182
  void display_as_XML(FILE * fd = stdout);
 
183
 
 
184
private:
 
185
  int64_t *m_value;            // the array of values
 
186
 
 
187
  void _setValues(size_t n, int64_t *value);
 
188
  int _convertStringToInt(char *val, unsigned *ival, LogFieldAliasMap * map);
 
189
 
 
190
  // -- member functions that are not allowed --
 
191
  LogFilterInt();
 
192
  LogFilterInt & operator=(LogFilterInt & rhs);
 
193
};
 
194
 
 
195
bool filters_are_equal(LogFilter * filt1, LogFilter * filt2);
 
196
 
 
197
 
 
198
/*-------------------------------------------------------------------------
 
199
  LogFilterList
 
200
  -------------------------------------------------------------------------*/
 
201
class LogFilterList
 
202
{
 
203
public:
 
204
  LogFilterList();
 
205
  ~LogFilterList();
 
206
  bool operator==(LogFilterList &);
 
207
 
 
208
  void add(LogFilter * filter, bool copy = true);
 
209
  bool toss_this_entry(LogAccess * lad);
 
210
  LogFilter *find_by_name(char *name);
 
211
  void clear();
 
212
 
 
213
  LogFilter *first() const { return m_filter_list.head; }
 
214
  LogFilter *next(LogFilter * here) const { return (here->link).next; }
 
215
 
 
216
  unsigned count();
 
217
  void display(FILE * fd = stdout);
 
218
  void display_as_XML(FILE * fd = stdout);
 
219
 
 
220
  bool does_conjunction() const { return m_does_conjunction;  };
 
221
  void set_conjunction(bool c) { m_does_conjunction = c;  };
 
222
 
 
223
private:
 
224
  Queue<LogFilter> m_filter_list;
 
225
 
 
226
  bool m_does_conjunction;
 
227
  // If m_does_conjunction = true
 
228
  // toss_this_entry returns true
 
229
  // if ANY filter tosses entry away.
 
230
  // If m_does_conjunction = false,
 
231
  // toss this entry returns true if
 
232
  // ALL filters toss away entry
 
233
 
 
234
  // -- member functions that are not allowed --
 
235
  LogFilterList(const LogFilterList & rhs);
 
236
  LogFilterList & operator=(const LogFilterList & rhs);
 
237
};
 
238
 
 
239
 
 
240
/*-------------------------------------------------------------------------
 
241
  Inline functions
 
242
  -------------------------------------------------------------------------*/
 
243
 
 
244
/*-------------------------------------------------------------------------
 
245
  _checkCondition
 
246
 
 
247
  check all values for a matching condition
 
248
 
 
249
  the arguments to the function are:
 
250
 
 
251
  - a function f of type OperatorFunction that determines if the
 
252
    condition is true for a single filter value. Note that this function
 
253
    must return 0 if the condition is true.
 
254
  - the value of the field from the log record
 
255
  - the length of this field
 
256
  - the array of filter values to compare to note that we pass this as an
 
257
    argument because it can be either m_value or m_value_uppercase
 
258
  - a LengthCondition argument that determines if the length of the field value
 
259
    must be equal or larger to the length of the filter value (this is to
 
260
    compare strings only if really needed
 
261
    ------------------------------------------------------------------------*/
 
262
 
 
263
inline bool
 
264
LogFilterString::_checkCondition(OperatorFunction f,
 
265
                                 const char *field_value, size_t field_value_length, char **val, LengthCondition lc)
 
266
{
 
267
  bool retVal = false;
 
268
 
 
269
  // make single value case a little bit faster by taking it out of loop
 
270
  //
 
271
  if (m_num_values == 1) {
 
272
    switch (lc) {
 
273
    case DATA_LENGTH_EQUAL:
 
274
      retVal = (field_value_length == *m_length ? ((*f) (field_value, *val) == 0 ? true : false) : false);
 
275
      break;
 
276
    case DATA_LENGTH_LARGER:
 
277
      retVal = (field_value_length > *m_length ? ((*f) (field_value, *val) == 0 ? true : false) : false);
 
278
      break;
 
279
    default:
 
280
      ink_assert(!"LogFilterString::checkCondition " "unknown LengthCondition");
 
281
    }
 
282
  } else {
 
283
    size_t i;
 
284
    switch (lc) {
 
285
    case DATA_LENGTH_EQUAL:
 
286
      for (i = 0; i < m_num_values; ++i) {
 
287
        // condition is satisfied if f returns zero
 
288
        if (field_value_length == m_length[i] && (*f) (field_value, val[i]) == 0) {
 
289
          retVal = true;
 
290
          break;
 
291
        }
 
292
      }
 
293
      break;
 
294
    case DATA_LENGTH_LARGER:
 
295
      for (i = 0; i < m_num_values; ++i) {
 
296
        // condition is satisfied if f returns zero
 
297
        if (field_value_length > m_length[i] && (*f) (field_value, val[i]) == 0) {
 
298
          retVal = true;
 
299
          break;
 
300
        }
 
301
      }
 
302
      break;
 
303
    default:
 
304
      ink_assert(!"LogFilterString::checkCondition " "unknown LengthCondition");
 
305
    }
 
306
  }
 
307
  return retVal;
 
308
}
 
309
 
 
310
#endif