------------------------------------------------------------ revno: 13132 revision-id: squid3@treenet.co.nz-20140502075133-fi3qci7uuo8neriq parent: squid3@treenet.co.nz-20140502074918-2mfpjgx14tqse6tr author: Christos Tsantilas committer: Amos Jeffries branch nick: 3.4 timestamp: Fri 2014-05-02 00:51:33 -0700 message: Logformat annotation fixes 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 ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20140502075133-fi3qci7uuo8neriq # target_branch: http://bzr.squid-cache.org/bzr/squid3/3.4 # testament_sha1: 5f9b3f388b33b59b5cbe57fb5a01bed0b58d3cee # timestamp: 2014-05-02 07:53:53 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/3.4 # base_revision_id: squid3@treenet.co.nz-20140502074918-\ # 2mfpjgx14tqse6tr # # Begin patch === modified file 'src/Notes.cc' --- src/Notes.cc 2013-11-29 10:55:53 +0000 +++ src/Notes.cc 2014-05-02 07:51:33 +0000 @@ -144,15 +144,15 @@ } const char * -NotePairs::find(const char *noteKey) const +NotePairs::find(const char *noteKey, const char *sep) const { static String value; value.clean(); for (Vector::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 @@ for (Vector::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; === modified file 'src/Notes.h' --- src/Notes.h 2013-11-29 10:55:53 +0000 +++ src/Notes.h 2014-05-02 07:51:33 +0000 @@ -140,7 +140,7 @@ * 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. === modified file 'src/cf.data.pre' --- src/cf.data.pre 2014-05-02 07:47:32 +0000 +++ src/cf.data.pre 2014-05-02 07:51:33 +0000 @@ -3700,10 +3700,22 @@ 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: === modified file 'src/format/Format.cc' --- src/format/Format.cc 2013-07-15 15:47:00 +0000 +++ src/format/Format.cc 2014-05-02 07:51:33 +0000 @@ -1076,31 +1076,36 @@ #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; === modified file 'src/format/Token.cc' --- src/format/Token.cc 2013-07-15 15:47:00 +0000 +++ src/format/Token.cc 2014-05-02 07:51:33 +0000 @@ -404,6 +404,8 @@ case LFT_REPLY_HEADER: + case LFT_NOTE: + if (data.string) { char *header = data.string; char *cp = strchr(header, ':'); @@ -538,6 +540,25 @@ 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. === modified file 'src/format/Token.h' --- src/format/Token.h 2014-01-12 02:14:21 +0000 +++ src/format/Token.h 2014-05-02 07:51:33 +0000 @@ -27,18 +27,7 @@ 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 @@ ByteCode_t type; const char *label; - union { + struct { char *string; struct {