Update of "log"
Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Artifact ID: | 552813bd7501ae16377ead9771fae1d221780ad5 |
---|---|
Page Name: | log |
Date: | 2015-01-06 14:00:39 |
Original User: | mario |
Mimetype: | text/x-markdown |
Parent: | 3a890c1e485e4c70f11167b8872a9f2a29a1a184 (diff) |
Next | 6d802b9a804045e7be2b8f14c8eaa27bec32d738 |
Structured and hierarchical logging with :token-parametric API
- State: experimental
- Category: logging
- Features: journaling, structured, hierarchical
- Backend: SQLite,
JSON,fluentd - Signature: hybrid, parametric
logStruck ł
implements a logging API and SQLite/JSON storage backend.
- It's purpose is storing structured log data, and it tries to retain log event hierarchies.
- Implements a hybrid and terse function interface.
- And accepts plain string messages, Ruby-style
:token
categorizers and placeholders, and understands array params. - Implicitly captures and maps PHP errors, unhandled exceptions, and most importantly
assert()
ions.
Unlike other PHP logging frameworks it's not a primarily text/line-oriented message dump.
Quick example
Basic invocations are along the lines of:
ł(':warn', ':wikiauth', "User doesn't have permission", $pageObj, ':vars', $_SESSION);
All the fun is in the :token
literals, and passing arrays or objects.
Database scheme, primary fields
All columns in the database scheme are primary fields. Any extra data/values go into the context
array.
<style> table.dbstruct { width: 85%; margin-left: 5%; } table.dbstruct tr:nth-child(2n) { background: #efefef; } </style>
i | PRIM | Where i is the primary index, g the event group, and p the parent reference. |
g | INT | |
p | INT | |
timestamp | REAL | Timestamp with microseconds. |
timestr | TEXT | ISO DateTime string. In GMT/UTC of course. |
host | TEXT | Hostname. |
pri | INT | Priority number (0…7). |
prio | TEXT | Priority string (emerg…info) |
source | TEXT | log|sys|lang|excpt|assert |
errno | INT | 0…32767 |
app | TEXT | AppName.php |
section | TEXT | Application structure / module / part / section. |
file | TEXT | path/file.php |
line | INT | 125 |
version | TEXT | Meta data from source code. |
message | TEXT | Primary log event message string. |
doc | TEXT | Extra documentation / long message / href. |
backtrace | JSON | Array of :backtrace |
code | TEXT | Extracted code context (3 lines). |
vars | JSON | Main $vars[] array. |
context | JSON | Additional / user-defined fields. |
Priority levels | ||
---|---|---|
:debug | 7 | Low-level debug events. |
:info | 6 | Process flow infos etc. |
:notice, :note | 5 | Lowest priority language notices. |
:warning, :warn | 4 | Warnings. |
:error, :err | 3 | PHP or system error. |
:critical, :crit | 2 | This can't be good. |
:alert, :alrt | 1 | Turn on the bat light. |
:emergency, :emerg | 0 | Someone call the president. |
Source / generator | ||
:log | Application origin, normal/manual log calls. | |
:sys | System-level events and errno codes. | |
:lang | Language errors, warnings, notices, etc. | |
:exception | Langauge/runtime exceptions. | |
:assert | Assert() warnings. | |
Field names | ||
Any database column / primary field name can be represented as :token . It's pretty much only useful to use :vars however to map the following array parameter. | ||
Injector calls | ||
:backtrace | Populates backtrace. | |
:server | Inserts $_SERVER array into context . | |
:file | Uncovers file and line from backtrace. | |
:version | Reads out meta data (file/scm version, and section) from script comments. | |
:code | Inserts 3 lines of code context. | |
:p | Tries to deduce log event hierarchy from prior calls, sections, and backtraces. (Not yet implemented.) |
Any other :token
name can be used freely to classify and group your application flow. They'll be used as section names.
Setup
You obviously need a readily available log.db
SQLite store. Keep it DOCUMENT_ROOT-relative, so it's easy to declare on instantion:
ł::$db = "$_SERVER[DOCUMENT_ROOT]/config/log.db";
ł::$app = "YourAppID";
You can of course manually load the library. Most autoloaders would already load it up with that snippet (even PSR-x ones, and they'd even be accidentially correct for once with case-sensitive Unicode lookups here).
While you ought to use :section
names for logging calls, you can also override the default through your application flow with:
ł::$section = "forum";
Or likewise adapt properties of the global logger group ł()->section=..
.
Notes / Rationale
So, this is all either genius, or completely bonkers.
Entirely intended as userland runtime; only suitable for wee projects.
The function name ł isn't completely settled on. (Maybe a bit too much novelty strive.)
Most logging libraries in PHP are inherently text-store trussed.
Reformatting/parsing into struct-backends is often an afterthought at best.Extensibility of the database scheme is easily done, but not planned for.
Alternative logging backends are best implemented in branches. It doesn't make sense to impose a configuration-centric instantiation. (However making
$ł->db
just a Callable would be trivial.)”Complexity seldomly abets security“. Long-winded logger instantiation, message formatters, and backend filters don't encourage diligent use.
Inspired by structlog, cabin, journald, graylog, PEAR log even, and logstash/fluentd.
The fancy ':token' signature is used in place of named params and constant literals in PHP.
Currently just inserts one-dimensional events. The API mapping is too crude still for spatial message/section/prio collections.
ToDo
Log events are only associated to a primary group event as of now. The
:p
filter will allow to regroup events automatically from context information.Alternatively
$p = ł("first"); ł("second", "p:$p");
can control it manually.The alternative JSON file-append store just keeps event-local ids/groups=1/parent ids. This needs an insertion transaction or trigger for reconverting into a SQLite store. (Probably simple.)
Investigate whether logstahs, fluentd or graylog2 make suitable targets. Neither seems to provide incremental log ids on submission. Otherwise each would require a lot log processing customizations to make a suitable backend.