This software is a lightweight user of the pftel-client
library that allows for logging to a remote logging service. Both stand-alone and modular use cases are supported. At the moment only minimal coverage of server API is provided.
pflog
is a simple app that is both a stand alone client as well as a module for logging to a pftel
telemetry server.
For on the metal installations, pip
it:
pip install pflog
docker pull fnndsc/pflog
To use pflog
in script mode you simply call the script with appropriate arguments (and of course this assumes you have a server instance at the $PFTEL
location)
export PFTEL=http://localhost:22223 # obviously change this as needed
pflog \
--log "Hello, world!" \
--pftelURL $PFTEL \
--verbosity 1 \
To use pflog
in python module mode, you declare an object and instantiate with a dictionary of values. The dictionary keys are identical to the script CLI keys:
from pflog import pflog
log:pflog.Pflog = pflog.Pflog( {
'log' : 'Hello, world!',
'pftelURL' : 'http://localhost:22223',
'verbosity' : '1'
}
)
d_tlog:dict = log.run()
# You can use this same object to log more messages:
log('This is another message')
log('and so is this!')
This writes messages to a logObject
called default under a logCollection
that is the timestamp of the event transmission. Within the logCollection
will be logEvent
s prefixed by an incremental counter, so 000-event
, 001-event
, etc.
The python module additionally offers a convience function pfprint
that offers a function-like throw back to C-style fprintf
while hiding the complexity of creating and using a Pflog
object:
pfprint('https://some.telemetry.server/api/v1/weather/MA/boston', 'Brrr... it is freezing today!')
will log the message Brr... it is freezing today!
in the event called boston
of the collection MA
of the set/object called weather
. Note that each call of pfprint
will create effectively a singleton object and a new connection to the telemetry server that is not reused (unlike the snippet above).
A decorator called tel_logTime
is also available. In the simplest case
@tel_logTime
weather_model(arg1, arg2)
will simply print the total execution time of the function weather_model
. This information can be additionally logged to a telemetry service using
@tel_logTime(
pftelDB = 'https://some.telemetry.server/ap1/v1/weather/MA/boston-%timestamp',
log = 'Weather prediction execTime'
)
weather_model(arg1, arg2)
which will record the execution time of the function to the pftelDB
. Note that the %timestamp
in the event
field boston-%timestamp
will be parsed at runtime with as a pftag
string and appropriately substituted. The log = 'Weather prediction execTime'
is simply an optional logging string that is also written to the log event. Equivalently one could do
@tel_logTime(
pftelDB = 'https://some.telemetry.server/ap1/v1/weather/MA/event',
event = 'boston-%timestamp'
log = 'Weather prediction execTime'
)
weather_model(arg1, arg2)
Finally, note the special case where the function to be decorated contains a python Namespace
with an attribute called pftelDB
. In this case, the decorator will determine the pftelDB
from the decorated function's arguments. This is particularly useful when the main entry point for a python program uses these options and we wish to log telemetry:
# Imagine we have a python program called 'weather_app' and it has a CLI option:
weather_app --pftelDB https://some.telemetry.server/ap1/v1/weather/MA/boston-%timestamp
# In python, assuming we have parsed the CLI with Argparser into a Namespace variable
# called 'options', we could simply do
@tel_logTime
main(options)
And the decorator will determine pftelDB
from the options
. For simplicity the event
and log
named args have been omitted. Note that the first decorator example was assumed to not have a Namespace
in either arg1
nor arg2
.
--pftelURL <pftelURL> | --pftelDB <URLDBpath>
The URL of the pftel instance. Typically:
--pftelURL http://some.location.somewhere:22223
either this or '--pftelDB' MUST be specified. See below for --pftelDB.
--log <logMessage>
The actual message to log. Use quotes to protect messages that
contain spaces:
--log "Hello, world!"
[--logObject <logObjectInPTFEL>] "default"
[--logCollection <logCollectionInPFTEL>] `timestamp`
[--logEvent <logEventInPFTEL>] "event"
[--appName <appName>]
[--execTime <execTime>]
Logs are stored within the pftel database in
`{logObjectInPFTEL}`/`{logCollectionInPFTEL}`/`{logEventInPFTEL}`
if not specified, use defaults as shown. The <appName> and <execTime>
are stored within the <logEventInPFTEL>.
[--pftelDB <DBURLpath>]
This is an alternate CLI that specifies a DB POST URL:
--pftelDB <URLpath>/<logObject>/<logCollection>/<logEvent>
for example
--pftelDB http://localhost:22223/api/v1/weather/massachusetts/boston
Indirect parsing of each of the object, collection, event strings is
available through `pftag` so any embedded pftag SGML is supported. So
http://localhost:22223/api/vi/%platform/%timestamp_strmsk|**********_/%name
would be parsed to, for example:
http://localhost:22223/api/vi/Linux/2023-03-11/posix
[--asyncio]
If specified, use asyncio, else do sync calls.
[--detailed]
If specified, return detailed responses from the server.
[--test]
If specified, run a small internal test on multi-logger calls.
[--pftelUser <user>] ("chris")
The name of the pftel user. Reserved for future use.
[--inputdir <inputdir>]
An optional input directory specifier. Reserverd for future use.
[--outputdir <outputdir>]
An optional output directory specifier. Reserved for future use.
[--man]
If specified, show this help page and quit.
[--verbosity <level>]
Set the verbosity level. The app is currently chatty at level 0 and level 1
provides even more information.
[--debug]
If specified, toggle internal debugging. This will break at any breakpoints
specified with 'Env.set_trace()'
[--debugTermsize <253,62>]
Debugging is via telnet session. This specifies the <cols>,<rows> size of
the terminal.
[--debugHost <0.0.0.0>]
Debugging is via telnet session. This specifies the host to which to connect.
[--debugPort <7900>]
Debugging is via telnet session. This specifies the port on which the telnet
session is listening.
To debug, the simplest mechanism is to trigger the internal remote telnet session with the --debug
CLI. Then, in the code, simply add Env.set_trace()
calls where appropriate. These can remain in the codebase (i.e. you don't need to delete/comment them out) since they are only live when a --debug
flag is passed.
Run unit tests using pytest
. Coming soon!
-30-