Skip to content

Commit 352b885

Browse files
nnshah1rmccorm4
andauthored
Add documentation on logging formats
--------- Co-authored-by: Ryan McCormick <[email protected]>
1 parent 15212fd commit 352b885

File tree

2 files changed

+140
-9
lines changed

2 files changed

+140
-9
lines changed

docs/protocol/extension_logging.md

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ the `$string` representation of the log setting and the “value” is a `$strin
6969
`$bool`, or `$number` representation of the setting value. Currently, the
7070
following log settings are defined:
7171

72-
- "log_file" : a `$string` parameter defining the file where the log outputs will be saved. If an empty string is specified, log outputs will stream to the console.
72+
- "log_file" : a `$string` log file location where the log outputs will be saved. If empty, log outputs are streamed to the console.
7373

7474
- "log_info" : a `$boolean` parameter that controls whether the Triton server logs INFO level messages.
7575

@@ -117,8 +117,14 @@ $log_setting_request =
117117
}
118118
```
119119

120-
When a `$log_setting` JSON is received (defined above), only the specified
121-
settings will be updated.
120+
When a `$log_setting` JSON is received (defined above), only the
121+
specified settings will be updated. Currently, the following log
122+
settings (described above) can be updated:
123+
- "log_info"
124+
- "log_warning"
125+
- "log_error"
126+
- "log_verbose_level"
127+
- "log_format"
122128

123129
### Example Usage
124130
The logging protocol extension can be invoked using the curl library in the following manner (assuming
@@ -196,3 +202,74 @@ message LogSettingsResponse
196202
map<string, SettingValue> settings = 1;
197203
}
198204
```
205+
206+
## Logging Formats
207+
208+
The logging extension offers two logging formats. The formats have a
209+
common set of fields but differ in how the timestamp for a log entry
210+
is represented. Messages are serialized according to JSON encoding
211+
rules by default. This behavior can be disabled by setting the
212+
environment variable TRITON_SERVER_ESCAPE_LOG_MESSAGES to "0" when
213+
launching the server but can not be changed through the logging
214+
extension.
215+
216+
Log entries can be single-line or multi-line. Multi-line entries have
217+
a single optional heading followed by the structured representation of
218+
an object such as a table or protobuf message. Multi-line entries end
219+
when the next log entry begins.
220+
221+
1. TRITONSERVER_LOG_DEFAULT
222+
223+
### Single-line Entry
224+
```
225+
<level><month><day><hour>:<min>:<sec>.<usec> <pid> <file>:<line>] <message>
226+
```
227+
Example:
228+
```
229+
I0520 20:03:25.829575 3355 model_lifecycle.cc:441] "AsyncLoad() 'simple'"
230+
```
231+
### Multi-line Entry
232+
```
233+
<level><month><day><hour>:<min>:<sec>.<usec> <pid> <file>:<line>] <heading>
234+
<object>
235+
```
236+
Example:
237+
238+
```
239+
I0520 20:03:25.912303 3355 server.cc:676]
240+
+--------+---------+--------+
241+
| Model | Version | Status |
242+
+--------+---------+--------+
243+
| simple | 1 | READY |
244+
+--------+---------+--------+
245+
```
246+
247+
248+
2. TRITONSERVER_LOG_ISO8601
249+
250+
### Single-line Entry
251+
```
252+
<year>-<month>-<day>T<hour>:<min>:<sec>Z <level> <pid> <file>:<line>] <message>
253+
```
254+
255+
Example:
256+
```
257+
2024-05-20T20:03:26Z I 3415 model_lifecycle.cc:441] "AsyncLoad() 'simple'"
258+
```
259+
260+
### Multi-line Entry
261+
```
262+
<year>-<month>-<day>T<hour>:<min>:<sec>Z <level> <pid> <file>:<line>] <heading>
263+
<object>
264+
```
265+
266+
Example:
267+
268+
```
269+
2024-05-20T20:03:26Z I 3415 server.cc:676]
270+
+--------+---------+--------+
271+
| Model | Version | Status |
272+
+--------+---------+--------+
273+
| simple | 1 | READY |
274+
+--------+---------+--------+
275+
```

qa/L0_logging/log_format_test.py

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,51 @@ def validate_table(table_rows):
280280

281281
@validator
282282
def validate_message(message, escaped):
283+
"""message field validator
284+
285+
Messages can be single line or multi-line. In the multi-line case
286+
messages have the form:
287+
288+
<heading>\n
289+
<object>
290+
291+
Where heading is an optional string (escaped with normal escaping
292+
rules) and object is a structured representation of an object such
293+
as a table or protobuf. The only objects currently allowed are:
294+
295+
* Tables (triton::common::table_printer)
296+
297+
* Model config protobuf messages
298+
299+
300+
301+
Parameters
302+
----------
303+
message : str
304+
message portion of log record (may be multiple lines)
305+
escaped : bool
306+
whether the message is escaped
307+
308+
Raises
309+
------
310+
Exception If message is expected to be escaped but is not
311+
or object doesn't match formatting
312+
313+
Examples
314+
--------
315+
316+
validate_message("foo",escaped=True) -> Exception
317+
validate_message('"foo"', escaped=True) -> pass
318+
validate_message('"foo"\nfoo',escaped=True) -> Exception
319+
validate_message('"foo"\n+--------+---------+--------+\n' \
320+
'| Model | Version | Status |\n' \
321+
'+--------+---------+--------+\n' \
322+
'| simple | 1 | READY |\n' \
323+
'+--------+---------+--------+',
324+
escaped=True) -> pass
325+
326+
"""
327+
283328
split_message = message.split("\n")
284329
heading = split_message[0]
285330
obj = split_message[1:] if len(split_message) > 1 else []
@@ -300,7 +345,7 @@ def validate_message(message, escaped):
300345
elif escaped:
301346
validate_protobuf(obj)
302347
else:
303-
# if not escaped we can't
348+
# if not escaped and not table we can't
304349
# guarantee why type of object is present
305350
pass
306351

@@ -315,9 +360,7 @@ def _setup(self, request):
315360
self._server_options["log-error"] = 1
316361
self._server_options["log-warning"] = 1
317362
self._server_options["log-format"] = "default"
318-
self._server_options["model-repository"] = os.path.abspath(
319-
os.path.join(module_directory, "log_models")
320-
)
363+
self._server_options["model-repository"] = test_model_directory
321364
self._server_process = None
322365
self._server_options["log-file"] = os.path.join(
323366
test_logs_directory, test_case_name + ".server.log"
@@ -436,11 +479,22 @@ def test_injection(self, log_format, format_regex, injected_record):
436479
triton_client = httpclient.InferenceServerClient(
437480
url="localhost:8000", verbose=False
438481
)
439-
while not triton_client.is_server_ready():
482+
483+
# TODO Refactor server launch, shutdown into reusable class
484+
wait_time = 10
485+
486+
while wait_time and not triton_client.is_server_ready():
440487
time.sleep(1)
488+
wait_time -= 1
441489

442-
while not triton_client.is_model_ready("simple"):
490+
while wait_time and not triton_client.is_model_ready("simple"):
443491
time.sleep(1)
492+
wait_time -= 1
493+
494+
if not triton_client.is_server_ready() or not triton_client.is_model_ready(
495+
"simple"
496+
):
497+
raise Exception("Model or Server not Ready")
444498

445499
except Exception as e:
446500
self._shutdown_server()

0 commit comments

Comments
 (0)