BoxLang 🚀 A New JVM Dynamic Language Learn More...
A minimal, self-contained ColdBox module that ships LogBox entries to
a Stachebox
instance over HTTP. It replaces the logstash module (and
its bundled cbelasticsearch, hyper and
cbrestbasehandler dependencies) for applications that
only send logs to a remote Stachebox — the
transmission: "api" mode.
The stock setup was: logstash module in api
mode, posting entries to a central Stachebox instance. No local
Elasticsearch exists on the application servers. Despite that, the
application intermittently failed to boot after a restart:
lucee.runtime.exp.LockException: a timeout occurred after 20 seconds trying to
acquire a exclusive lock with name [module....activation.logstash]
followed by key [cbController] doesn't exist on every
request — the site never came back online.
Root cause, in the logstash module (v3.1.1):
api mode the module registers logstash.models.logging.APIAppender.APIAppender
extends
cbelasticsearch.models.logging.LogstashAppender and
only overrides logMessage(). It inherits onRegistration().onRegistration() when the appender is
registered — during module activation, inside ColdBox's exclusive
per-module activation lock.onRegistration() runs
ensureDataStream(): ILM policy, ingest pipeline,
index/component templates — all against the
cbelasticsearch client, whose unconfigured default host
is 127.0.0.1:9200.application[cbController] is never set, and the
application stays down.So an appender whose only job was "POST JSON to a URL" was taking the site down over an Elasticsearch it was never supposed to talk to — and dragged in three dependency modules to do it.
Everything the old stack actually did for us fits in one appender CFC
with no dependencies (models/StacheboxAppender.cfc):
cbelasticsearch LogstashAppender produced
(ECS-style keys, source-context frames for exceptions,
error.stack_trace/frames/extrainfo
as JSON strings, yyyy-mm-dd'T'HH:nn: ssZZ timestamps).stachebox.signature hash (same fields, same order), so
occurrences keep grouping with entries logged by the old module.{ "entry": ..., "dataStream": ... }
with a Bearer token to the Stachebox API from a fire-and-forget
cfthread — the request never waits on the log target,
and a send failure only prints to stderr.Module activation does zero I/O: onLoad() just registers
the appender on the root logger. An unreachable Stachebox can no
longer affect application startup or requests.
Deliberately dropped from the old module: direct-to-Elasticsearch
mode, the log-receiving API endpoints, detached appenders, and the
userInfoUDF hook. If per-user context is ever needed
again, extend the user key in marshallLogObject().
Available on ForgeBox:
box install singleFileStacheboxAppender
Source and issue tracker: github.com/akitogo/singleFileStacheboxAppender
In config/Coldbox.cfc (or config/modules/singleFileStacheboxAppender.cfc):
moduleSettings = {
"singleFileStacheboxAppender" = {
"apiUrl" : "https://stachebox.example.com/logstash/api/logs",
"apiAuthToken" : "<bearer token>",
"applicationName" : "my-app",
"levelMin" : "FATAL",
"levelMax" : "INFO"
}
};
| Setting | Default | Purpose |
|---|---|---|
enabled
| true
| Master switch |
apiUrl
| (empty — appender not registered) | Stachebox log intake endpoint |
apiAuthToken
| (empty) | Authorization: Bearer token |
applicationName
| application name | Grouping label in Stachebox |
dataStream
| logs-coldbox-logstash-appender
| Data stream name sent with each entry |
levelMin
| FATAL
| Minimum severity |
levelMax
| INFO
| Maximum severity |
$
box install singleFileStacheboxAppender