GUI editor to tame mod_security rules

⌈⌋ branch:  modseccfg


Check-in [43e6843f24]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix mkdocs/RTD table styling per sed
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 43e6843f24088d7c654a9105eff987799f0063aaffda42a6bc382559ce6e36af
User & Date: mario 2020-12-28 22:12:01
Context
2020-12-29
14:26
Add manpages (seemingly setup(data_files=…) knows where to place them.) check-in: 28405ca3cf user: mario tags: trunk
2020-12-28
22:12
Fix mkdocs/RTD table styling per sed check-in: 43e6843f24 user: mario tags: trunk
13:39
replace fontawesome arrows with unicode equivalents check-in: ce5c7ccf26 user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.

26
27
28
29
30
31
32
33


whl:
	pandoc logfmt1/README.md -o logfmt1/README.rst
	cd logfmt1 && ./setup.py bdist_wheel
whl_up:
	twine upload dist/logfmt*

docs:
	cd logfmt1 ; PYTHONPATH=. mkdocs build









|
>
>
26
27
28
29
30
31
32
33
34
35
whl:
	pandoc logfmt1/README.md -o logfmt1/README.rst
	cd logfmt1 && ./setup.py bdist_wheel
whl_up:
	twine upload dist/logfmt*

docs:
	cd logfmt1 ; PYTHONPATH=. mkdocs build -v -v -v
	sed -i 's/table\.docutils/table/g' logfmt1/html/css/theme.css 
	

Changes to logfmt1/docs/custom.css.

1
2



3
4
5
6
7
8
9
body {
    font-size: 115% !important;



}

.doc-object {
    margin-top: 2.5rem;
}

blockquote {
|
|
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
body, * {
    font-size: 1.1rem !important;
}
code {
    font-size: 0.75rem !important;
}

.doc-object {
    margin-top: 2.5rem;
}

blockquote {

Changes to logfmt1/docs/fmt.md.


1
2
3
4
5
6
7
8
9

> | ❮❗❯ | This is all very provisional. (First draft. Names might still change.) |
> | ---- | ----------------------------------- |


## Global .fmt database

While each log file should be accompanied by a [.fmt descriptor](log.fmt.md),
the global database in `/usr/share/logfmt/` contains a full .fmt field
definition for each class.
>
|
<







1
2

3
4
5
6
7
8
9
!!! Warning
    ❮❗❯ This is all very provisional. (First draft. Names might still change.)



## Global .fmt database

While each log file should be accompanied by a [.fmt descriptor](log.fmt.md),
the global database in `/usr/share/logfmt/` contains a full .fmt field
definition for each class.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
        },
        "glob": ["/var/log/apache*/*acc*.log"]
    }

It usually does not describe a default "record" format (like the local .log.fmt descriptors do).


## class

The class in the global database is largely decorative.  The filenames
instead define the heritage of rules/fields.  The "class" as declared by
a .log.fmt is mapped onto `/usr/share/logfmt/application.variant.fmt`.

 * Usually there's just one variant level per log type. But the lookup is
   supposed to be mildly recursive.
 * Essentially it should merge `*.log.fmt` with `appclass.variant.fmt` and
   `appclass.fmt` applied last, so the most specific definitions are retained.
 * There's also a generic "grok" class. But the patterns therein are largely
   static (not build from variable format strings).
 * Some special classes like "json" might exist. (Not supported by logfmt1)


### record

The "record" entry is not usually present in the global .fmt definition. 
Some super specific variant definitions (for example apache.error.fmt) or
static formats (syslog.fmt) might however.


### separator

Most log formats use spaces for separating %placeholder fields.  And simpler
implementations might just split up the "record" declaration on this.


## placeholder

While logfmt1 instead uses a regex definition of possible %placeholder
strings to map onto fields. It should account for prefixes/suffixes, unless
those got cleared by the `rewrite` map.

Not all formatstrings use `%\w+` to signal placeholders. In nginx for instance
the sigil `$\w+` introduces placeholders (variable names, really).







|














|






|





|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
        },
        "glob": ["/var/log/apache*/*acc*.log"]
    }

It usually does not describe a default "record" format (like the local .log.fmt descriptors do).


### class

The class in the global database is largely decorative.  The filenames
instead define the heritage of rules/fields.  The "class" as declared by
a .log.fmt is mapped onto `/usr/share/logfmt/application.variant.fmt`.

 * Usually there's just one variant level per log type. But the lookup is
   supposed to be mildly recursive.
 * Essentially it should merge `*.log.fmt` with `appclass.variant.fmt` and
   `appclass.fmt` applied last, so the most specific definitions are retained.
 * There's also a generic "grok" class. But the patterns therein are largely
   static (not build from variable format strings).
 * Some special classes like "json" might exist. (Not supported by logfmt1)


#### record

The "record" entry is not usually present in the global .fmt definition. 
Some super specific variant definitions (for example apache.error.fmt) or
static formats (syslog.fmt) might however.


#### separator

Most log formats use spaces for separating %placeholder fields.  And simpler
implementations might just split up the "record" declaration on this.


### placeholder

While logfmt1 instead uses a regex definition of possible %placeholder
strings to map onto fields. It should account for prefixes/suffixes, unless
those got cleared by the `rewrite` map.

Not all formatstrings use `%\w+` to signal placeholders. In nginx for instance
the sigil `$\w+` introduces placeholders (variable names, really).
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
   into a regex.
 * Therefore meta characters (such as `|` or `[]`) have to be
   taken care of.  Which is what the `rewrite` map is lazily used for.
 * Better implementations might look up the placeholders, and automatically
   escape the rest of the the "record" format string.


## fields

The core of the global .fmt definitions are the field lists.  Each defines a
static %F placeholder and associaties it with a default field name (id:) and
regex (rx:) or even a grok definition (grok:).

| key |	purpose |
|-----|---------|
| %F |	JSON key: static placeholder string (not a regex itself) |
| id |	field identifier, as specified by the application (internal name) |
| rx |	regex which %F placeholder gets replaced with |
| grok | alternatively to regex, %F might be turned into %PATTERN:id |
| type | "int" and "float" could designate strictly numeric fields |

 * As part of the regex transformation, a `%F` could be turned into
   `(?<id>\S+)` for instance.
 * If there's any unnamed capture group `(…)`, it should be augmented
   into a named capture group - instead of the whole match. (To account
   for implicit wrapping.)
 * The `rx` itself might however specify named subgroups (like request_line
   in Apache logs, itself comprised of _method, _path, _protocol, or the
   datetime made up of tm_wday, tm_year, tm_whatever).
 * `\S+` is also used as fallback for entirely undefined placeholders
   (no expand definition matched) in logfmt1.
 * `grok` isn't currently used, but might allow for simpler transformations
   (indirectly into a grok pattern, and later a regex).


## expand

The expand declarations are used to construct unknown fields/placeholders. 
Instead of static %placeholders, each entry describes a regex to detect
new/variant placeholders.  Thus it simply can be applied before
separator/placeholder are looked at, to augment the known `fields` list.

| key |	purpose |
|-----|---------|
| `%\{(\w+)\}t` | JSON key: a regex to detect mutable placeholders |
| id |	name for newly created fields entry, might use captures $1 |
| rx |	for static definitions (often just \S+)|
| if_quoted |	alternative regex, if placeholder was enclosed in "%\w+" quotes |
| class | recurse into other .fmt types|
| record | can be set to $2 if class: recursion is defined |


 * Typically it suffices to specify the `id` and `rx` field.
 * If no `id` is given, then the regex capture is normalized into
   an identifier (non-alphanumerics stripped, all lowercased).
 * But the `id` or `record` value might be set with regex captures
   (e.g. `$1` or `$2`) or compound values (`"id": "newfield_$1"`).
 * And logfmt1 allows to recurse into other format types per `class`







|





|

|
|
|

















|






|
|
|
|
|
|
|
|
>







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
   into a regex.
 * Therefore meta characters (such as `|` or `[]`) have to be
   taken care of.  Which is what the `rewrite` map is lazily used for.
 * Better implementations might look up the placeholders, and automatically
   escape the rest of the the "record" format string.


### fields

The core of the global .fmt definitions are the field lists.  Each defines a
static %F placeholder and associaties it with a default field name (id:) and
regex (rx:) or even a grok definition (grok:).

| key | purpose |
|-----|---------|
|`%F`| **JSON key**: static placeholder string (not a regex itself) |
| id | field identifier, as specified by the application (internal name) |
| rx | regex which %F placeholder gets replaced with |
| grok | alternatively to regex, %F might be turned into %PATTERN:id |
| type | "int" and "float" could designate strictly numeric fields |

 * As part of the regex transformation, a `%F` could be turned into
   `(?<id>\S+)` for instance.
 * If there's any unnamed capture group `(…)`, it should be augmented
   into a named capture group - instead of the whole match. (To account
   for implicit wrapping.)
 * The `rx` itself might however specify named subgroups (like request_line
   in Apache logs, itself comprised of _method, _path, _protocol, or the
   datetime made up of tm_wday, tm_year, tm_whatever).
 * `\S+` is also used as fallback for entirely undefined placeholders
   (no expand definition matched) in logfmt1.
 * `grok` isn't currently used, but might allow for simpler transformations
   (indirectly into a grok pattern, and later a regex).


### expand

The expand declarations are used to construct unknown fields/placeholders. 
Instead of static %placeholders, each entry describes a regex to detect
new/variant placeholders.  Thus it simply can be applied before
separator/placeholder are looked at, to augment the known `fields` list.

| key      |  purpose                                               |
|----------|--------------------------------------------------------|
| `%\{(\w+)\}t` | **JSON key**: a regex to detect mutable placeholders  |
| id     | name for newly created fields entry, might use captures´ $1|
| rx     | for static definitions (often just \S+)                  |
|if_quoted| alternative regex, if placeholder was enclosed in "%\w+" quotes|
| class  | recurse into other .fmt types                            |
| record | can be set to $2 if class: recursion is defined          |


 * Typically it suffices to specify the `id` and `rx` field.
 * If no `id` is given, then the regex capture is normalized into
   an identifier (non-alphanumerics stripped, all lowercased).
 * But the `id` or `record` value might be set with regex captures
   (e.g. `$1` or `$2`) or compound values (`"id": "newfield_$1"`).
 * And logfmt1 allows to recurse into other format types per `class`
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
to application-internal names. (For instance `log_pfn_register(…,…,cb_id)`
names in Apache). And those aren't always the more commonly used identifiers.

Thus aliases makes sense not just for convenience, but also to be compatible
to other common names (e.g. w3c extend log format names like `cs-time`).


### container

Is utilized by logopen() to extract additional fields (lists even) from one
of the existing fields.  This is usually done at row traversal.  And makes
sense for application-specific subformats in logs.  Such as any `key=value`
lists in the main message field.

> Still not sure if automatic list conversion is a good idea.

### glob

Might be used by log processors to look up a log class, based on file names,
if no .log.fmt is declared.


### "#comment": fields

Documentation entries in the .fmt files have keys starting with `#`. For example
`"#license":` or `"#origin":`. Which is simpler than using JSON with
comments (JSOL).

-----

## Other format files


> This section is about fictional features.


### .grok definitions

> Not implemented yet.

The logfmt/ directory might also contain .grok files, which get transformed
into .fmt structures. (Probably with the grok: parameter for fields, and
a grok: pattern table alongside regular fields:).

There's already a pretransformed `grok.fmt`, which however requires
`%{GROK:%{PATTERN:id}}` references currently.


### .lnav formats

> Not implemented yet.

Likewise could we use lnav .json format definitions. Those are static
too, however.








|








|













|

>
|


|











|






176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
to application-internal names. (For instance `log_pfn_register(…,…,cb_id)`
names in Apache). And those aren't always the more commonly used identifiers.

Thus aliases makes sense not just for convenience, but also to be compatible
to other common names (e.g. w3c extend log format names like `cs-time`).


#### container

Is utilized by logopen() to extract additional fields (lists even) from one
of the existing fields.  This is usually done at row traversal.  And makes
sense for application-specific subformats in logs.  Such as any `key=value`
lists in the main message field.

> Still not sure if automatic list conversion is a good idea.

#### glob

Might be used by log processors to look up a log class, based on file names,
if no .log.fmt is declared.


### "#comment": fields

Documentation entries in the .fmt files have keys starting with `#`. For example
`"#license":` or `"#origin":`. Which is simpler than using JSON with
comments (JSOL).

-----

### Other format files

!!! Note
    This section is about fictional features.


#### .grok definitions

> Not implemented yet.

The logfmt/ directory might also contain .grok files, which get transformed
into .fmt structures. (Probably with the grok: parameter for fields, and
a grok: pattern table alongside regular fields:).

There's already a pretransformed `grok.fmt`, which however requires
`%{GROK:%{PATTERN:id}}` references currently.


#### .lnav formats

> Not implemented yet.

Likewise could we use lnav .json format definitions. Those are static
too, however.

Changes to logfmt1/html/css/theme.css.

cannot compute difference between binary files

Changes to logfmt1/html/css/theme_extra.css.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  white-space: pre;
  word-wrap: normal;
  display: block;
  padding: 12px;
  font-size: 12px;
}

/**
 * Fix code colors
 *
 * https://github.com/mkdocs/mkdocs/issues/2027
 */
.rst-content code {
    color: #E74C3C;
}

.rst-content pre code {
    color: #000;
    background: #f8f8f8;
}

/*
 * Fix link colors when the link text is inline code.
 *
 * https://github.com/mkdocs/mkdocs/issues/718
 */
a code {
    color: #2980B9;







<
<
<
<
<
<
<
<
<
<
<
<
<
<







24
25
26
27
28
29
30














31
32
33
34
35
36
37
  white-space: pre;
  word-wrap: normal;
  display: block;
  padding: 12px;
  font-size: 12px;
}















/*
 * Fix link colors when the link text is inline code.
 *
 * https://github.com/mkdocs/mkdocs/issues/718
 */
a code {
    color: #2980B9;

Changes to logfmt1/html/custom.css.

1
2



3
4
5
6
7
8
9
body {
    font-size: 115% !important;



}

.doc-object {
    margin-top: 2.5rem;
}

blockquote {
|
|
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
body, * {
    font-size: 1.1rem !important;
}
code {
    font-size: 0.75rem !important;
}

.doc-object {
    margin-top: 2.5rem;
}

blockquote {

Changes to logfmt1/html/fmt.html.

61
62
63
64
65
66
67


































68
69
70
71
72
73
74
                    </li>
                </ul>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="fmt.html">global .fmt db</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#sample">sample</a>
    </li>


































    </ul>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="update-logfmt.html">update-logmt</a>
                    </li>
                </ul>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
                    </li>
                </ul>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="fmt.html">global .fmt db</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#sample">sample</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#class">class</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#record">record</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#separator">separator</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#placeholder">placeholder</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#rewrite">rewrite</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#fields">fields</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#expand">expand</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#alias">alias</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#container">container</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#glob">glob</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#comment-fields">"#comment": fields</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#other-format-files">Other format files</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#grok-definitions">.grok definitions</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#lnav-formats">.lnav formats</a>
    </li>
        </ul>
    </li>
    </ul>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="update-logfmt.html">update-logmt</a>
                    </li>
                </ul>
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <blockquote>
<table>
<thead>
<tr>
<th>❮❗❯</th>
<th>This is all very provisional. (First draft. Names might still change.)</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</blockquote>
<h2 id="global-fmt-database">Global .fmt database</h2>
<p>While each log file should be accompanied by a <a href="log.fmt.html">.fmt descriptor</a>,
the global database in <code>/usr/share/logfmt/</code> contains a full .fmt field
definition for each class.</p>
<p>Most notably the <code>"fields":</code> and <code>"placeholder":</code> are used to construct the
regex for a <code>"record":</code> string definition.</p>
<h3 id="sample">sample</h3>







|
|
<
<
<
|
|
<
<
<
<
<
<
<
<
<







138
139
140
141
142
143
144
145
146



147
148









149
150
151
152
153
154
155
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <div class="admonition warning">
<p class="admonition-title">Warning</p>



<p>❮❗❯ This is all very provisional. (First draft. Names might still change.)</p>
</div>









<h2 id="global-fmt-database">Global .fmt database</h2>
<p>While each log file should be accompanied by a <a href="log.fmt.html">.fmt descriptor</a>,
the global database in <code>/usr/share/logfmt/</code> contains a full .fmt field
definition for each class.</p>
<p>Most notably the <code>"fields":</code> and <code>"placeholder":</code> are used to construct the
regex for a <code>"record":</code> string definition.</p>
<h3 id="sample">sample</h3>
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
        <span class="p">}</span>
    <span class="p">},</span>
    <span class="s2">&quot;glob&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;/var/log/apache*/*acc*.log&quot;</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>

<p>It usually does not describe a default "record" format (like the local .log.fmt descriptors do).</p>
<h2 id="class">class</h2>
<p>The class in the global database is largely decorative.  The filenames
instead define the heritage of rules/fields.  The "class" as declared by
a .log.fmt is mapped onto <code>/usr/share/logfmt/application.variant.fmt</code>.</p>
<ul>
<li>Usually there's just one variant level per log type. But the lookup is
   supposed to be mildly recursive.</li>
<li>Essentially it should merge <code>*.log.fmt</code> with <code>appclass.variant.fmt</code> and
   <code>appclass.fmt</code> applied last, so the most specific definitions are retained.</li>
<li>There's also a generic "grok" class. But the patterns therein are largely
   static (not build from variable format strings).</li>
<li>Some special classes like "json" might exist. (Not supported by logfmt1)</li>
</ul>
<h3 id="record">record</h3>
<p>The "record" entry is not usually present in the global .fmt definition. 
Some super specific variant definitions (for example apache.error.fmt) or
static formats (syslog.fmt) might however.</p>
<h3 id="separator">separator</h3>
<p>Most log formats use spaces for separating %placeholder fields.  And simpler
implementations might just split up the "record" declaration on this.</p>
<h2 id="placeholder">placeholder</h2>
<p>While logfmt1 instead uses a regex definition of possible %placeholder
strings to map onto fields. It should account for prefixes/suffixes, unless
those got cleared by the <code>rewrite</code> map.</p>
<p>Not all formatstrings use <code>%\w+</code> to signal placeholders. In nginx for instance
the sigil <code>$\w+</code> introduces placeholders (variable names, really).</p>
<h3 id="rewrite">rewrite</h3>
<p>A list/map of regex to apply before any transformations or field lookups. 
Which can be used to mask or simplify placeholder definitions (for instance
clean up the Apache conditional prefixes) or regex meta characters.</p>
<ul>
<li>The <code>record</code> field starts as a static string, but is meant to be turned
   into a regex.</li>
<li>Therefore meta characters (such as <code>|</code> or <code>[]</code>) have to be
   taken care of.  Which is what the <code>rewrite</code> map is lazily used for.</li>
<li>Better implementations might look up the placeholders, and automatically
   escape the rest of the the "record" format string.</li>
</ul>
<h2 id="fields">fields</h2>
<p>The core of the global .fmt definitions are the field lists.  Each defines a
static %F placeholder and associaties it with a default field name (id:) and
regex (rx:) or even a grok definition (grok:).</p>
<table>
<thead>
<tr>
<th>key</th>
<th>purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td>%F</td>
<td>JSON key: static placeholder string (not a regex itself)</td>
</tr>
<tr>
<td>id</td>
<td>field identifier, as specified by the application (internal name)</td>
</tr>
<tr>
<td>rx</td>







|












|



|


|

















|












|
|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
        <span class="p">}</span>
    <span class="p">},</span>
    <span class="s2">&quot;glob&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;/var/log/apache*/*acc*.log&quot;</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div>

<p>It usually does not describe a default "record" format (like the local .log.fmt descriptors do).</p>
<h3 id="class">class</h3>
<p>The class in the global database is largely decorative.  The filenames
instead define the heritage of rules/fields.  The "class" as declared by
a .log.fmt is mapped onto <code>/usr/share/logfmt/application.variant.fmt</code>.</p>
<ul>
<li>Usually there's just one variant level per log type. But the lookup is
   supposed to be mildly recursive.</li>
<li>Essentially it should merge <code>*.log.fmt</code> with <code>appclass.variant.fmt</code> and
   <code>appclass.fmt</code> applied last, so the most specific definitions are retained.</li>
<li>There's also a generic "grok" class. But the patterns therein are largely
   static (not build from variable format strings).</li>
<li>Some special classes like "json" might exist. (Not supported by logfmt1)</li>
</ul>
<h4 id="record">record</h4>
<p>The "record" entry is not usually present in the global .fmt definition. 
Some super specific variant definitions (for example apache.error.fmt) or
static formats (syslog.fmt) might however.</p>
<h4 id="separator">separator</h4>
<p>Most log formats use spaces for separating %placeholder fields.  And simpler
implementations might just split up the "record" declaration on this.</p>
<h3 id="placeholder">placeholder</h3>
<p>While logfmt1 instead uses a regex definition of possible %placeholder
strings to map onto fields. It should account for prefixes/suffixes, unless
those got cleared by the <code>rewrite</code> map.</p>
<p>Not all formatstrings use <code>%\w+</code> to signal placeholders. In nginx for instance
the sigil <code>$\w+</code> introduces placeholders (variable names, really).</p>
<h3 id="rewrite">rewrite</h3>
<p>A list/map of regex to apply before any transformations or field lookups. 
Which can be used to mask or simplify placeholder definitions (for instance
clean up the Apache conditional prefixes) or regex meta characters.</p>
<ul>
<li>The <code>record</code> field starts as a static string, but is meant to be turned
   into a regex.</li>
<li>Therefore meta characters (such as <code>|</code> or <code>[]</code>) have to be
   taken care of.  Which is what the <code>rewrite</code> map is lazily used for.</li>
<li>Better implementations might look up the placeholders, and automatically
   escape the rest of the the "record" format string.</li>
</ul>
<h3 id="fields">fields</h3>
<p>The core of the global .fmt definitions are the field lists.  Each defines a
static %F placeholder and associaties it with a default field name (id:) and
regex (rx:) or even a grok definition (grok:).</p>
<table>
<thead>
<tr>
<th>key</th>
<th>purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>%F</code></td>
<td><strong>JSON key</strong>: static placeholder string (not a regex itself)</td>
</tr>
<tr>
<td>id</td>
<td>field identifier, as specified by the application (internal name)</td>
</tr>
<tr>
<td>rx</td>
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
   in Apache logs, itself comprised of _method, _path, _protocol, or the
   datetime made up of tm_wday, tm_year, tm_whatever).</li>
<li><code>\S+</code> is also used as fallback for entirely undefined placeholders
   (no expand definition matched) in logfmt1.</li>
<li><code>grok</code> isn't currently used, but might allow for simpler transformations
   (indirectly into a grok pattern, and later a regex).</li>
</ul>
<h2 id="expand">expand</h2>
<p>The expand declarations are used to construct unknown fields/placeholders. 
Instead of static %placeholders, each entry describes a regex to detect
new/variant placeholders.  Thus it simply can be applied before
separator/placeholder are looked at, to augment the known <code>fields</code> list.</p>
<table>
<thead>
<tr>
<th>key</th>
<th>purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>%\{(\w+)\}t</code></td>
<td>JSON key: a regex to detect mutable placeholders</td>
</tr>
<tr>
<td>id</td>
<td>name for newly created fields entry, might use captures $1</td>
</tr>
<tr>
<td>rx</td>
<td>for static definitions (often just \S+)</td>
</tr>
<tr>
<td>if_quoted</td>







|














|



|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
   in Apache logs, itself comprised of _method, _path, _protocol, or the
   datetime made up of tm_wday, tm_year, tm_whatever).</li>
<li><code>\S+</code> is also used as fallback for entirely undefined placeholders
   (no expand definition matched) in logfmt1.</li>
<li><code>grok</code> isn't currently used, but might allow for simpler transformations
   (indirectly into a grok pattern, and later a regex).</li>
</ul>
<h3 id="expand">expand</h3>
<p>The expand declarations are used to construct unknown fields/placeholders. 
Instead of static %placeholders, each entry describes a regex to detect
new/variant placeholders.  Thus it simply can be applied before
separator/placeholder are looked at, to augment the known <code>fields</code> list.</p>
<table>
<thead>
<tr>
<th>key</th>
<th>purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>%\{(\w+)\}t</code></td>
<td><strong>JSON key</strong>: a regex to detect mutable placeholders</td>
</tr>
<tr>
<td>id</td>
<td>name for newly created fields entry, might use captures´ $1</td>
</tr>
<tr>
<td>rx</td>
<td>for static definitions (often just \S+)</td>
</tr>
<tr>
<td>if_quoted</td>
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
<h3 id="alias">alias</h3>
<p>Maps alternative/more common field names onto the declared field <code>id</code>s.</p>
<p>To get to some state of standardization, the field ids usually refer
to application-internal names. (For instance <code>log_pfn_register(…,…,cb_id)</code>
names in Apache). And those aren't always the more commonly used identifiers.</p>
<p>Thus aliases makes sense not just for convenience, but also to be compatible
to other common names (e.g. w3c extend log format names like <code>cs-time</code>).</p>
<h3 id="container">container</h3>
<p>Is utilized by logopen() to extract additional fields (lists even) from one
of the existing fields.  This is usually done at row traversal.  And makes
sense for application-specific subformats in logs.  Such as any <code>key=value</code>
lists in the main message field.</p>
<blockquote>
<p>Still not sure if automatic list conversion is a good idea.</p>
</blockquote>
<h3 id="glob">glob</h3>
<p>Might be used by log processors to look up a log class, based on file names,
if no .log.fmt is declared.</p>
<h3 id="comment-fields">"#comment": fields</h3>
<p>Documentation entries in the .fmt files have keys starting with <code>#</code>. For example
<code>"#license":</code> or <code>"#origin":</code>. Which is simpler than using JSON with
comments (JSOL).</p>
<hr />
<h2 id="other-format-files">Other format files</h2>
<blockquote>

<p>This section is about fictional features.</p>
</blockquote>
<h3 id="grok-definitions">.grok definitions</h3>
<blockquote>
<p>Not implemented yet.</p>
</blockquote>
<p>The logfmt/ directory might also contain .grok files, which get transformed
into .fmt structures. (Probably with the grok: parameter for fields, and
a grok: pattern table alongside regular fields:).</p>
<p>There's already a pretransformed <code>grok.fmt</code>, which however requires
<code>%{GROK:%{PATTERN:id}}</code> references currently.</p>
<h3 id="lnav-formats">.lnav formats</h3>
<blockquote>
<p>Not implemented yet.</p>
</blockquote>
<p>Likewise could we use lnav .json format definitions. Those are static
too, however.</p>
              
            </div>







|







|







|
|
>

|
|








|







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
<h3 id="alias">alias</h3>
<p>Maps alternative/more common field names onto the declared field <code>id</code>s.</p>
<p>To get to some state of standardization, the field ids usually refer
to application-internal names. (For instance <code>log_pfn_register(…,…,cb_id)</code>
names in Apache). And those aren't always the more commonly used identifiers.</p>
<p>Thus aliases makes sense not just for convenience, but also to be compatible
to other common names (e.g. w3c extend log format names like <code>cs-time</code>).</p>
<h4 id="container">container</h4>
<p>Is utilized by logopen() to extract additional fields (lists even) from one
of the existing fields.  This is usually done at row traversal.  And makes
sense for application-specific subformats in logs.  Such as any <code>key=value</code>
lists in the main message field.</p>
<blockquote>
<p>Still not sure if automatic list conversion is a good idea.</p>
</blockquote>
<h4 id="glob">glob</h4>
<p>Might be used by log processors to look up a log class, based on file names,
if no .log.fmt is declared.</p>
<h3 id="comment-fields">"#comment": fields</h3>
<p>Documentation entries in the .fmt files have keys starting with <code>#</code>. For example
<code>"#license":</code> or <code>"#origin":</code>. Which is simpler than using JSON with
comments (JSOL).</p>
<hr />
<h3 id="other-format-files">Other format files</h3>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>This section is about fictional features.</p>
</div>
<h4 id="grok-definitions">.grok definitions</h4>
<blockquote>
<p>Not implemented yet.</p>
</blockquote>
<p>The logfmt/ directory might also contain .grok files, which get transformed
into .fmt structures. (Probably with the grok: parameter for fields, and
a grok: pattern table alongside regular fields:).</p>
<p>There's already a pretransformed <code>grok.fmt</code>, which however requires
<code>%{GROK:%{PATTERN:id}}</code> references currently.</p>
<h4 id="lnav-formats">.lnav formats</h4>
<blockquote>
<p>Not implemented yet.</p>
</blockquote>
<p>Likewise could we use lnav .json format definitions. Those are static
too, however.</p>
              
            </div>

Changes to logfmt1/mkdocs.yml.

9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
    - global .fmt db: fmt.md
    - update-logmt: update-logfmt.md
    - logex: logex.md
theme:
#  name: materia
#  name: bootstrap386
#  name: ivory
#  name: material
  name: readthedocs
repo_url: https://fossil.include-once.org/modseccfg/wiki/logfmt1
markdown_extensions:
  - admonition
  - codehilite

#  - mkautodoc
plugins:
  - mkdocstrings
extra_css:
    - custom.css
use_directory_urls: false
  








|





>


|





9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    - global .fmt db: fmt.md
    - update-logmt: update-logfmt.md
    - logex: logex.md
theme:
#  name: materia
#  name: bootstrap386
#  name: ivory
  name: material
  name: readthedocs
repo_url: https://fossil.include-once.org/modseccfg/wiki/logfmt1
markdown_extensions:
  - admonition
  - codehilite
  - tables
#  - mkautodoc
plugins:
    - mkdocstrings
extra_css:
    - custom.css
use_directory_urls: false