]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Logformat annotation fixes
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 2 May 2014 07:51:33 +0000 (00:51 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Fri, 2 May 2014 07:51:33 +0000 (00:51 -0700)
Currently note values printed with "%note" formating code, which contain non
alphanumeric characters, were quoted and quotes were then escaped, resulting
in bizarre logged rendition of empty or simple values (often received from
various helpers):
      %22-%22
      %22Default_Google%22
      %22pg13,US%22

This patch:
- does not use quotes to print annotations

- allow system admin to define a separator to use for logged
  annotations. The %note logformat accepts the following argument:
     [name][:separator]
  The separator can be one of the ',' ';' or ':'.
  By default, multiple note values are separated with "," and multiple
  notes are separated with "\r\n". When logging named notes with
  %{name}note, the explicitly configured separator is used between note
  values. When logging all notes with %note, the explicitly configured
  separator is used between individual notes. There is currently no way to
  specify both value and notes separators when logging all notes with %note.

- makes the Format::Token::data a struct (now is a union) and initialize
  Format::Token::data data members in Format::Token::Token constructor.

This is a Measurement Factory project

src/Notes.cc
src/Notes.h
src/cf.data.pre
src/format/Format.cc
src/format/Token.cc
src/format/Token.h

index a981ad2feeec3bc42a916abd5873f83afa097c72..00039565f6ad47befcf128585bb043c554db25bf 100644 (file)
@@ -144,15 +144,15 @@ NotePairs::~NotePairs()
 }
 
 const char *
-NotePairs::find(const char *noteKey) const
+NotePairs::find(const char *noteKey, const char *sep) const
 {
     static String value;
     value.clean();
     for (Vector<NotePairs::Entry *>::const_iterator  i = entries.begin(); i != entries.end(); ++i) {
         if ((*i)->name.cmp(noteKey) == 0) {
             if (value.size())
-                value.append(", ");
-            value.append(ConfigParser::QuoteString((*i)->value));
+                value.append(sep);
+            value.append((*i)->value);
         }
     }
     return value.size() ? value.termedBuf() : NULL;
@@ -166,7 +166,7 @@ NotePairs::toString(const char *sep) const
     for (Vector<NotePairs::Entry *>::const_iterator  i = entries.begin(); i != entries.end(); ++i) {
         value.append((*i)->name);
         value.append(": ");
-        value.append(ConfigParser::QuoteString((*i)->value));
+        value.append((*i)->value);
         value.append(sep);
     }
     return value.size() ? value.termedBuf() : NULL;
index 341b482716ef1c18df168a2e90e261cc9f2aba50..47950d4c88cb261a0983490e8589d8b50e798251 100644 (file)
@@ -140,7 +140,7 @@ public:
      * Returns a comma separated list of notes with key 'noteKey'.
      * Use findFirst instead when a unique kv-pair is needed.
      */
-    const char *find(const char *noteKey) const;
+    const char *find(const char *noteKey, const char *sep = ",") const;
 
     /**
      * Returns the first note value for this key or an empty string.
index 88f4c0c6e0e61c35bbba1f6d43276287829122db..777d73c24ae4e394e3ab72bc07210094b264cd30 100644 (file)
@@ -3700,10 +3700,22 @@ DOC_START
                err_code    The ID of an error response served by Squid or
                                a similar internal error identifier.
                err_detail  Additional err_code-dependent error information.
-               note    The meta header specified by the argument. Also
+               note    The annotation specified by the argument. Also
                        logs the adaptation meta headers set by the
                        adaptation_meta configuration parameter.
-                       If no argument given all meta headers logged.
+                       If no argument given all annotations logged.
+                       The argument may include a separator to use with
+                       annotation values:
+                            name[:separator]
+                       By default, multiple note values are separated with ","
+                       and multiple notes are separated with "\r\n".
+                       When logging named notes with %{name}note, the
+                       explicitly configured separator is used between note
+                       values. When logging all notes with %note, the
+                       explicitly configured separator is used between
+                       individual notes. There is currently no way to
+                       specify both value and notes separators when logging
+                       all notes with %note.
 
        Connection related format codes:
 
index e737280e8e572cd44ef8f2aa76d5fdd47cecea59..10d1f67625fba97bdd33b038bb5c33209ac12794 100644 (file)
@@ -1076,31 +1076,36 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
 #endif
 
         case LFT_NOTE:
-            if (fmt->data.string) {
+            tmp[0] = fmt->data.header.separator;
+            tmp[1] = '\0';
+            if (fmt->data.header.header && *fmt->data.header.header) {
+                const char *separator = tmp;
 #if USE_ADAPTATION
                 Adaptation::History::Pointer ah = al->request ? al->request->adaptHistory() : Adaptation::History::Pointer();
                 if (ah != NULL && ah->metaHeaders != NULL) {
-                    if (const char *meta = ah->metaHeaders->find(fmt->data.string))
+                    if (const char *meta = ah->metaHeaders->find(fmt->data.header.header, separator))
                         sb.append(meta);
                 }
 #endif
                 if (al->notes != NULL) {
-                    if (const char *note = al->notes->find(fmt->data.string)) {
+                    if (const char *note = al->notes->find(fmt->data.header.header, separator)) {
                         if (sb.size())
-                            sb.append(", ");
+                            sb.append(separator);
                         sb.append(note);
                     }
                 }
                 out = sb.termedBuf();
                 quote = 1;
             } else {
+                // if no argument given use default "\r\n" as notes separator
+                const char *separator = fmt->data.string ? tmp : "\r\n";
 #if USE_ADAPTATION
                 Adaptation::History::Pointer ah = al->request ? al->request->adaptHistory() : Adaptation::History::Pointer();
                 if (ah != NULL && ah->metaHeaders != NULL && !ah->metaHeaders->empty())
-                    sb.append(ah->metaHeaders->toString());
+                    sb.append(ah->metaHeaders->toString(separator));
 #endif
                 if (al->notes != NULL && !al->notes->empty())
-                    sb.append(al->notes->toString());
+                    sb.append(al->notes->toString(separator));
 
                 out = sb.termedBuf();
                 quote = 1;
index 1dd60e6c504efdf730f063552033cea3266ff9b1..6f67b144e7782e34490d17864c8d354c7ca644d8 100644 (file)
@@ -404,6 +404,8 @@ done:
 
     case LFT_REPLY_HEADER:
 
+    case LFT_NOTE:
+
         if (data.string) {
             char *header = data.string;
             char *cp = strchr(header, ':');
@@ -538,6 +540,25 @@ done:
     return (cur - def);
 }
 
+Format::Token::Token() : type(LFT_NONE),
+                         label(NULL),
+                         widthMin(-1),
+                         widthMax(-1),
+                         quote(LOG_QUOTE_NONE),
+                         left(false),
+                         space(false),
+                         zero(false),
+                         divisor(1),
+                         next(NULL)
+{
+    data.string = NULL;
+    data.header.header = NULL; 
+    data.header.element = NULL;
+    data.header.separator = ',';
+}
+
+
+
 Format::Token::~Token()
 {
     label = NULL; // drop reference to global static.
index f8b3c6226490c8acefac0b08491e3ccc2b4f04e4..a50c38a722e10e3eb17aeff52924d80fca7d72e6 100644 (file)
@@ -27,18 +27,7 @@ class TokenTableEntry;
 class Token
 {
 public:
-    Token() : type(LFT_NONE),
-            label(NULL),
-            widthMin(-1),
-            widthMax(-1),
-            quote(LOG_QUOTE_NONE),
-            left(false),
-            space(false),
-            zero(false),
-            divisor(1),
-            next(NULL)
-    { data.string = NULL; }
-
+    Token();
     ~Token();
 
     /// Initialize the format token registrations
@@ -52,7 +41,7 @@ public:
 
     ByteCode_t type;
     const char *label;
-    union {
+    struct {
         char *string;
 
         struct {