This article shows how to send Prometheus metrics (Remote Write) to TNT4J-Streams via an HTTP servlet (WAR)—covering Prometheus setup, server and jKool/XRay sink configuration, deployment, parser setup, optional label-based filtering, and how data maps to activities/snapshots.
Quick Setup Steps
1) Configure Prometheus Remote Write
Configure the Prometheus remote write endpoint in your prometheus.yml, e.g.:
remote_write:
# - url: "https://app.cybench.io/tnt4j-streams-prom"
# name: "cybench_write"
- url: "http://localhost:8080/tnt4j-streams-servlet"
name: "local_write"
2) Copy Configuration Files
Copy configuration files to your web server configuration directory, e.g., <TOMCAT_DIR>/conf.
By default, TNT4J-Streams will try to use the internal configuration directory path /Catalina/localhost/tnt4j-streams:
log4j2.xml— log4j v2 configuration used by TNT4J-Streamstnt4j.properties— base TNT4J configurationtnt4j-common.properties— common TNT4J configurationtnt4j-streams.properties— TNT4J-Streams dedicated TNT4J configuration-
tnt-data-source.xml— TNT4J-Streams data source (stream) configuration, with a stream-dedicated TNT4J properties section.
Note (default sink): the default configuration broadcasts metrics to jKool/XRay (sink IDxray).<tnt4j-properties> <...> <property name="event.sink.factory.BroadcastSequence" value="xray"/> <...> </tnt4j-properties>
3) Set jKool/XRay Endpoint and Token
Change
https://stream.meshiq.comto your jKool/XRay streaming endpoint URL.Change the
xray-access-tokenplaceholder to your jKool/XRay streaming token if you are willing to stream into that repo.
4) Parsers Configuration
parsers.xml— TNT4J-Streams parsers configuration.
For most general cases,
there is no need to change
log4j2.xml,
tnt4j*.properties, or
parsers.xml. The only file that
usually requires changes is
tnt-data-source.xml.
5) Download the WAR Package
Download the latest TNT4J-Streams WAR package from GitHub Releases. It will be available in the Assets section of the release.
6) Deploy the Application
Deploy tnt4j-streams-<VERSION>.war or tnt4j-streams-servlet-<VERSION>.war to your web server webapps directory (e.g., <TOMCAT_DIR>/webapps).
Remove the version token from the WAR file name to preserve the web-app context on every deployment.
7) Start the Server
Start the web server, if it is not already running.
TL;DR
Build TNT4J-Streams Servlet
There are two ways to build the TNT4J-Streams WAR package:
When building the whole
tnt4j-streamsproject, Maven will producetnt4j-streams-<VERSION>.war, where all reactor-enabled modules and dependencies are built into thatWARpackage.When individually building the
tnt4j-streams-servletmodule, Maven will producetnt4j-streams-servlet-<VERSION>.war, where all module dependencies are built into thatWARpackage.
In either case, the WAR package contains classes and resources (like web.xml) provided by the tnt4j-streams-servlet module.
Configuration (Overview)
The Prometheus Remote Write streaming HTTP endpoint (servlet) configuration is a combination of:
Web-app deployment descriptor
web.xmlwithin theWARpackage (by default) or within your web server configuration directory, e.g.,<TOMCAT_DIR>/conf/Catalina/localhost/tnt4j-streamslog4j2.xmldefining log4j v2 configuration used by the TNT4J-Streams APITNT4J configuration properties files split into dedicated scopes (base, common, streams)
tnt-data-source.xmldefining stream configurationparsers.xmldefining parsers used by TNT4J-Streams to map metric fields to the TNT4J activities data model
For most general cases,
there is no need to change
web.xml,
log4j2.xml, tnt4j*.properties, or
parsers.xml files.
Web-App Deployment Descriptor (web.xml within WAR package)
Defines the servlet initialization parameter set and servlet mapping.
Init params
streams.configs.dir— TNT4J-Streams configuration files location path. It shall contain these files:tnt4j.properties,log4j2.xml, andtnt-data-source.xml. Optional if setting individual configuration files with init paramstnt4j.config,log4j2.config, andstreams.config.
Default value:${catalina.base}/conf/Catalina/localhost/tnt4j-streamstnt4j.config— TNT4J configuration file path.
Default value:tnt4j.propertieslog4j2.config— log4j v2 configuration file path.
Default value:log4j2.xmlstreams.config— TNT4J-Streams data source/parsers configuration file path.
Default value:tnt-data-source.xml
Servlet mapping
Default URL pattern:
/
log4j2
In general, the configuration is the same as for common TNT4J-Streams logging, except this config uses ${sys:catalina.base}/logs to locate generated log files.
Also note that loggers are named to match the stream-configuration-defined broadcasting sink IDs: ap and xray instead of prod and qa.
TNT4J
In general, the configuration is the same as common TNT4J-Streams TNT4J configuration, except the streams scope (tnt4j-streams.properties file) defines broadcasting sink IDs ap and xray to match the sink target endpoint.
Individual TNT4J stream-scope configuration is made in the tnt-data-source.xml file section <tnt4j-properties>.
Stream (tnt-data-source.xml)
Major entities in the stream configuration are
PrometheusMetricsStreamof classcom.jkoolcloud.tnt4j.streams.inputs.HttpServletStream, which picks up the HTTP POST–transmitted request payload as stream input data.<tnt4j-properties>section defining individual stream TNT4J configuration: propertyevent.sink.factory.BroadcastSequencedefines the broadcasting sinks for produced activities. The default configuration contains jKool/XRay (sink IDxray). The default set of sinks to broadcast stream-produced activities isxray.
<tnt4j-properties> <...> <property name="event.sink.factory.BroadcastSequence" value="xray"/> <...> </tnt4j-properties>
- The properties group starting
event.sink.factory.EventSinkFactory.xraydefines the jKool/XRay–dedicated sink configuration.- Change the jKool/XRay sink (id
xray) URL value (propertyevent.sink.factory.EventSinkFactory.xray.Url) to match your jKool/XRay instance. Default ishttps://stream.meshiq.com. - change the jKool/XRay sink (id
xray) token placeholder value (propertyevent.sink.factory.EventSinkFactory.xray.Token) to your jKool/XRay streaming token if you are willing to stream into that repo. Placeholder value isxray-access-token.
- Change the jKool/XRay sink (id
-
PrometheusParser— parser reference to bootstrap the incoming metrics data package.
Parsers (parsers.xml)
Unwraps Prometheus-sent metrics data packages into a collection of time-series maps, then allows metrics filtering (see Metrics filtering), and performs time-series map field-value parsing into TNT4J activities and snapshots.
This file defines these parsers:
PrometheusParser— bootstrap parser recognizing the received metrics data package format (binary, text, etc.).MetricsParserStr— parses Prometheus Remote Write request data if it was sent as JSON, picking a collection of time-series entries.TimeSeriesParser— aggregates all time-series entries provided byMetricsParserStrunder a singleACTIVITY.SnappyCompressedMetricsParser— converts Prometheus Snappy-compressed binary data to a collection of time-series maps and produces anACTIVITYentity containing snapshots for every time-series entry produced byTimeSeriesEntryParser.TimeSeriesEntryParser— builds a time-series–entry–map–parsedSNAPSHOTentity.MetricsMetaDataParser— time-series map fields group metadata parser.ExemplarsParser— time-series map fields group exemplars parser.SamplesParser— time-series map fields group samples parser.LabelsParser— time-series map fields group labels parser.
And these pre-parsers:
SnappyBinPreParser— performs Snappy-compressed binary data decompression.PrometheusReqMapPreParser— parses binary data into a PrometheusRemote.WriteRequestmessage and extracts it into a time-series entries map.
Metrics Filtering
You may want to stream only a subset of the provided time series. To filter time series by label, implement filtering logic in the SnappyCompressedMetricsParser parser field (embedded activity) MetricsDataProto transformation. The default transformation does not perform any filtering:
Collection<Map<String, ?>> tsColl = new ArrayList<>()
for (Map.Entry<String, Collection<Map<String, ?>>> tsCollE : $fieldValue.entrySet()) {
tsColl.addAll(tsCollE.getValue())
}
return tsColl
kafka_consumer time-series entries):import org.apache.commons.lang3.StringUtils
Collection<Map<String, ?>> tsColl = new ArrayList<> ()
for (Map.Entry<String, Collection<Map<String, ?>>> tsCollE : $fieldValue.entrySet ()) {
if (StringUtils.startsWithAny (tsCollE.getKey (), "kafka_consumer_")) { //NON-NLS
tsColl.addAll (tsCollE.getValue ())
}
}
return tsCollStreamed Metrics Data
For Prometheus Remote Write–provided metrics packages, TNT4J-Streams produces an ACTIVITY entity containing:
Name has value
PrometheusTimeSeriesStartTime/EndTime having current stream runtime timestamp
Time-series entries are placed as child SNAPSHOTs of that ACTIVITY entity. Each snapshot contains the following fields:
Labels group produces
Instance — value from group field
instanceJob — value from group field
jobType — value from group field
typeName — value from group field
name
Samples group produces
StartTime/EndTime — value from group field
timestampValue — value from group field
value
Metadata group produces
MetricType — value from group field
typeHelp — value from group field
helpMetricFamilyName — value from group field
familyUnit — value from group field
unit
Additional mappings
Category — value mapped from the time-series entry name to the JMX domain. Mapping is done in the
TimeSeriesEntryParserparser fielddomaintransformation.Name — value from labels group field
__name__
The rest of the metrics line fields are mapped into snapshot properties using their original names (1:1). Usually, these may be new or very rare fields.