Bridge Service Configuration Guide#
The MA DataPlatforms Bridge service uses multiple configuration sections to control various aspects of data streaming, processing, and integration. This guide provides comprehensive documentation for all configuration sections.
Configuration File Structure#
The configuration file is AppConfig.json when you run Bridge Service yourself (standalone or in Docker), and
BridgeServiceConfig.json when ADS launches it. Both have the same format — see
Choose your deployment for which file applies to you. It contains the following
top-level sections:
{
"StreamApiConfig": { ... },
"StreamSelectionConfig": { ... },
"BridgeConfig": { ... },
"EssentialsConfig": { ... },
"RdaConfig": { ... },
"DiskBackedBufferConfig": { ... },
"Serilog": { ... }
}
Overriding Configuration with Environment Variables#
Bridge Service loads AppConfig.json first, then applies any matching environment variables on
top of it — environment variables take precedence over values in the JSON file. This applies in
both deployment modes (standalone host and ADS-integrated).
Address nested configuration keys with a double underscore (__) between each segment:
$env:StreamApiConfig__BrokerUrl = "kafka-broker.company.com:9092"
$env:BridgeConfig__DataSource = "RaceTrack01"
Tip
Use environment variables for values you don't want committed to AppConfig.json — for
example broker credentials — instead of writing them into the file.
Note
Environment variables are read once at startup. Restart the Bridge Service after changing one.
1. StreamApiConfig#
Controls the Stream API integration and Kafka broker connectivity.
Properties#
| Property | Type | Default | Description |
|---|---|---|---|
StreamCreationStrategy |
int/enum | 2 | Strategy for creating Kafka topics/streams • 1 = PartitionBased• 2 = TopicBased (recommended) |
BrokerUrl |
string | "localhost:9092" | Kafka broker connection string |
PartitionMappings |
array | [] | Partition mapping configurations (PartitionBased only) |
IntegrateSessionManagement |
boolean | true | Enable session management integration |
IntegrateDataFormatManagement |
boolean | true | Enable data format management integration |
UseRemoteKeyGenerator |
boolean | false | Use remote key generator service |
RemoteKeyGeneratorServiceAddress |
string | "" | URL of remote key generator service |
InitialisationTimeoutSeconds |
int | 1 | Timeout in seconds for Stream API init |
Domain |
string | "" | Optional domain specification |
Security |
object | null | Kafka SASL/SSL credentials — see Kafka Security (SASL / SSL) below |
Example Configuration#
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "kafka-broker.company.com:9092",
"PartitionMappings": [],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"InitialisationTimeoutSeconds": 1,
"Domain": "Telemetry"
}
}
Kafka Security (SASL / SSL)#
If your Kafka broker requires authentication or an encrypted connection, add a Security object
inside StreamApiConfig. Security is only activated once you set SaslUsername, SslCaLocation,
or SslCertificateLocation — leave Security out entirely to connect without any security, which
is unchanged for existing unsecured deployments.
| Property | Type | Description |
|---|---|---|
SaslUsername |
string? | SASL username. Setting this activates security. |
SaslPassword |
string? | SASL password. |
Protocol |
string? | Plaintext, Ssl, SaslPlaintext, or SaslSsl. Defaults to SaslPlaintext once security is activated. |
Mechanism |
string? | Plain, ScramSha256, or ScramSha512. Defaults to Plain once security is activated. |
SslCaLocation |
string? | Path to the CA certificate (PEM) used to verify the broker's certificate. |
SslCertificateLocation |
string? | Path to the client certificate (PEM), for mutual TLS. Setting this activates security. |
SslKeyLocation |
string? | Path to the client private key (PEM), for mutual TLS. |
SslKeyPassword |
string? | Password for the client private key, if it's encrypted. |
| AppConfig.json | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 | |
| AppConfig.json | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 | |
| AppConfig.json | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
| AppConfig.json | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 | |
| AppConfig.json | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 | |
Tip
Bridge Service also reads environment variables,
so credentials can be supplied without writing them into AppConfig.json:
StreamApiConfig__Security__SaslUsername=myuser
StreamApiConfig__Security__SaslPassword=mypassword
Stream Creation Strategy Explained#
The Bridge service works with Stream API's two streaming strategies. Your choice affects how Bridge streams are mapped to Kafka topics.
Topic-Based Strategy (StreamCreationStrategy = 2)#
Each stream from the Bridge service maps to its own Kafka topic. This is simpler and recommended for most use cases.
How Mapping Works:
- Bridge uses
StreamSelectionConfigto determine stream names. - Each unique stream name creates a separate Kafka topic.
- Topic naming:
{Domain}.Data.{StreamName}
Example Scenario
Bridge Configuration:
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"Domain": "Production"
},
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "EngineTelemetry" },
{ "AppName": "Chassis*", "Stream": "ChassisTelemetry" },
{ "AppName": "Aero*", "Stream": "AeroTelemetry" }
]
}
}
Resulting Kafka Topics:
* Production.Data.EngineTelemetry (All Engine app groups)
* Production.Data.ChassisTelemetry (All Chassis app groups)
* Production.Data.AeroTelemetry (All Aero* app groups)
Use Topic-Based When:
- You have fewer than 100 unique streams.
- You want simple debugging (each stream has its own topic).
- Topic limits are not a concern.
- Message time alignment across streams is not important, or will be handled at the consumer level (note: Kafka does not align messages between topics).
Partition-Based Strategy (StreamCreationStrategy = 1)#
Multiple streams share a single Kafka topic but are distributed across different partitions. Requires explicit partition mappings in StreamApiConfig.
How Mapping Works:
- Bridge uses
StreamSelectionConfigto determine stream names. - Stream API uses
PartitionMappingsto assign each stream to a partition. - All streams share the same topic:
{Domain}.Data.MainDataSource. - IMPORTANT: Partition 0 is reserved by Stream API.
Example Scenario
Bridge Configuration:
{
"StreamApiConfig": {
"StreamCreationStrategy": 1,
"Domain": "Production",
"PartitionMappings": [
{ "Stream": "EngineTelemetry", "Partition": 1 },
{ "Stream": "ChassisTelemetry", "Partition": 2 },
{ "Stream": "AeroTelemetry", "Partition": 3 },
{ "Stream": "BrakeTelemetry", "Partition": 4 }
]
},
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "EngineTelemetry" },
{ "AppName": "Chassis*", "Stream": "ChassisTelemetry" },
{ "AppName": "Aero*", "Stream": "AeroTelemetry" },
{ "AppName": "Brake*", "Stream": "BrakeTelemetry" }
]
}
}
Resulting Kafka Topic with Partitions:
Topic: Production.Data.MainDataSource
* Partition 0: [Reserved by Stream API]
* Partition 1: EngineTelemetry data
* Partition 2: ChassisTelemetry data
* Partition 3: AeroTelemetry data
* Partition 4: BrakeTelemetry data
Critical Rules for Partition-Based
- Stream names in
StreamSelectionConfigMUST matchStreaminPartitionMappings. - Partition 0 is reserved - all mappings must use partition 1 and above.
- Each stream must have a unique partition number.
- Kafka topic must be created with enough partitions (max partition number + 1).
Use Partition-Based When:
- You have hundreds or thousands of streams.
- Kafka topic limits are a concern.
- You need better resource utilization.
- You need better resource utilization.
- You need time-aligned data across multiple streams - Kafka guarantees message order only within a single partition, so partition-based allows all streams to share one topic with proper temporal alignment.
Time-Aligned Data Consideration
For both Topic-Based and Partition-Based strategies: If you need time-aligned data across multiple application groups, map all of them to a single stream name in StreamSelectionConfig. This ensures:
- Topic-Based (Strategy 2): All data goes to one Kafka topic with aligned timestamps.
- Partition-Based (Strategy 1): All data goes to one partition within the topic with aligned timestamps.
Example for time-aligned data:
{
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "VehicleTelemetry" },
{ "AppName": "Chassis*", "Stream": "VehicleTelemetry" },
{ "AppName": "Aero*", "Stream": "VehicleTelemetry" },
{ "AppName": "Brake*", "Stream": "VehicleTelemetry" }
]
}
}
Stream Mapping Flow#
- Data arrives at Bridge with
AppName(e.g., "EngineData") StreamSelectionConfigmapsAppNameto Stream- Example: "EngineData" -> matches "Engine*" -> "EngineTelemetry"
- Stream API receives "EngineTelemetry" stream
StreamCreationStrategydetermines Kafka destination:- Topic-Based (Strategy 2): Writes to Kafka topic
Production.Data.EngineTelemetry. - Partition-Based (Strategy 1):
- Looks up "EngineTelemetry" in
PartitionMappings. - Finds Partition 1.
- Writes to
Production.Data.MainDataSource, Partition 1.
- Looks up "EngineTelemetry" in
- Topic-Based (Strategy 2): Writes to Kafka topic
2. StreamSelectionConfig#
Controls how data streams are mapped from application groups to Stream API streams, including wildcard pattern matching support.
Properties#
| Property | Type | Default | Description |
|---|---|---|---|
Auto |
boolean | true | Automatically map app names to stream names without transformation |
Mappings |
array | [] | Custom mappings from app names to streams with wildcard support (when Auto=false) |
Mappings Structure#
Each mapping entry contains:
| Field | Type | Description |
|---|---|---|
AppName |
string | Application group name or pattern (supports wildcards: *) |
Stream |
string | Target stream name in Stream API |
Wildcard Pattern Matching#
The AppName field supports wildcard patterns using the * character:
- Exact match:
"EngineData"- matches only "EngineData" - Prefix match:
"Engine*"- matches "EngineData", "EngineTemp", "EnginePressure" - Suffix match:
"*Telemetry"- matches "EngineTelemetry", "ChassisTelemetry" - Contains:
"*_Data_*"- matches any app name containing "Data"
Pattern Evaluation Rules:
- Patterns are evaluated in order of definition.
- First matching pattern wins.
- Case-insensitive matching.
- Results are cached for performance.
Example Configurations#
Auto Mode (Simple)#
{
"StreamSelectionConfig": {
"Auto": true
}
}
Manual Mapping (No Wildcards)#
{
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{
"AppName": "EngineData",
"Stream": "engine-telemetry-stream"
},
{
"AppName": "ChassisData",
"Stream": "chassis-telemetry-stream"
}
]
}
}
Wildcard Mapping (Flexible)#
{
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{
"AppName": "Engine*",
"Stream": "engine-telemetry-stream"
},
{
"AppName": "Chassis*",
"Stream": "chassis-telemetry-stream"
},
{
"AppName": "*Telemetry",
"Stream": "general-telemetry-stream"
},
{
"AppName": "Aero_*_Data",
"Stream": "aerodynamics-stream"
}
]
}
}
Best Practices#
- Ordering Matters: Place more specific patterns before general ones.
- Auto Mode: Use when stream names match app group names exactly.
- Wildcards: Use to reduce configuration complexity when dealing with many similar app groups.
3. BridgeConfig#
Controls core Bridge service behavior including processing units, data handling, and flow control strategies.
Properties#
| Property | Type | Default | Description |
|---|---|---|---|
DataSource |
string | "Default" | Name identifier for the data source |
UseStringIdentifier |
boolean | false | Use string-based identifiers instead of numeric IDs |
AdsTimeoutInSeconds |
int | 720 | Timeout in seconds for detecting session stop when no data is received from ADS (ATLAS Data Server) |
ProcessFlow |
enum | SequentialAll | Data processing flow strategy (see below for details) |
FeedPort |
int? | null | Optional port override for the data feed (see Feed Port and Metric Port Resolution) |
MetricPort |
int? | null | Optional port override for the Prometheus metrics endpoint (see Feed Port and Metric Port Resolution) |
LiveConcurrencyFactor |
int | 4 | Number of parallel processing units for live telemetry |
OffloadConcurrencyFactor |
int | 12 | Number of parallel processing units for offloaded (historical/replayed) telemetry |
OffloadProcessing |
boolean | true | Whether offloaded data is processed at all; when false, offloaded data is discarded instead of being written out |
OffloadStream |
string | "" (empty) | Optional stream name that offloaded data is routed to, instead of the default stream |
StandalonePgvList |
string[] | [] (empty) | PGV app IDs, as decimal or 0x-prefixed hex strings, that Bridge Service should accept as standalone and output data for (see below) |
Feed Port and Metric Port Resolution#
The feed port (data ingress) and the Prometheus metrics port are each resolved from multiple sources, in priority order:
- Feed port: the
-pcommand-line argument or theFEED_PORTenvironment variable. - Metric port: the
METRIC_PORTenvironment variable (there is no-mcommand-line argument). BridgeConfig.FeedPort/BridgeConfig.MetricPortinAppConfig.json(or the equivalentBridgeConfig__FeedPort/BridgeConfig__MetricPortenvironment variables described in Overriding Configuration with Environment Variables).- Built-in defaults: 9697 for the feed port, 10010 for the metric port.
Note
FEED_PORT and METRIC_PORT are read directly by the host process and take priority over
any BridgeConfig__FeedPort / BridgeConfig__MetricPort value — if a stale FEED_PORT
environment variable is set, it silently overrides a FeedPort you set in AppConfig.json.
ProcessFlow Strategies#
The ProcessFlow property controls how the Bridge service handles data flow and backpressure:
SequentialAll (Default)#
- Value:
"SequentialAll"or0 - Behavior: Processes all data sequentially without dropping any packets
- Use when: Data integrity is critical and you need to ensure every packet is processed
- Impact: May experience backpressure if downstream systems are slow
DropOldest#
- Value:
"DropOldest"or1 - Behavior: Drops oldest unprocessed data when buffers are full, prioritizing recent data
- Use when: Real-time data is more important than historical completeness
- Impact: Better performance under load, but some data may be dropped during high traffic
- Note: Applies per-session dropping strategy to maintain data freshness
Example Configuration#
{
"BridgeConfig": {
"DataSource": "RaceTrack01",
"UseStringIdentifier": true,
"LiveConcurrencyFactor": 16,
"AdsTimeoutInSeconds": 600,
"ProcessFlow": "SequentialAll"
}
}
Example with DropOldest Flow#
{
"BridgeConfig": {
"DataSource": "LiveTelemetry",
"UseStringIdentifier": true,
"LiveConcurrencyFactor": 24,
"AdsTimeoutInSeconds": 720,
"ProcessFlow": "DropOldest"
}
}
Performance Tuning#
LiveConcurrencyFactor: Controls the number of parallel processing units for live telemetry. Increase for higher throughput on multi-core systems. Higher values use more CPU.OffloadConcurrencyFactor: Controls the number of parallel processing units for offloaded (historical/replayed) telemetry. Increase for higher throughput on multi-core systems. Higher values use more CPU.OffloadProcessing: Set tofalseto discard offloaded data instead of processing it, if offload telemetry isn't needed downstream.AdsTimeoutInSeconds: Controls how long the Bridge waits without receiving data before considering a session stopped. Default is 720 seconds (12 minutes). Reduce for faster session timeout detection, increase if you expect longer gaps in data transmission.ProcessFlow: ChooseSequentialAllwhen data completeness is critical, orDropOldestwhen real-time performance is more important than historical completeness.
Standalone PGV List#
StandalonePgvList lists the PGV app IDs Bridge Service should accept as standalone. When data
from the ECU requests an app ID that's in this list, Bridge Service loads that PGV and starts
outputting data from that app. If the list is empty, or an app's ID isn't in it, Bridge Service
does not output data from that app.
Each entry is a string, parsed as decimal or (with a 0x/0X prefix) hexadecimal, and must fit
in the range 0-65535. Leading and trailing whitespace is trimmed.
| AppConfig.json | |
|---|---|
1 2 3 4 5 | |
4. EssentialsConfig#
Configuration files (CFG) and Parameter Group Values (PGV) are essential for data decoding.
Windows: empty paths fall back to ATLAS 9
On Windows, if CfgDirectoryPaths or PgvDirectoryPaths is empty, Bridge Service uses the config and PGV folders
set in ATLAS 9 for the Windows user running it. That is why an ADS-launched Bridge Service usually needs no
EssentialsConfig section.
Docker / Linux: both paths are required
There is no ATLAS 9 fallback outside Windows. If CfgDirectoryPaths or PgvDirectoryPaths is empty, Bridge
Service stops at startup with "DirectoryPaths needs to be specified in EssentialsConfig" — even when
RemoteConfigIndexerUrl is set.
Properties#
| Property | Type | Description |
|---|---|---|
CfgDirectoryPaths |
string[] | Array of directory paths containing CFG configuration files |
PgvDirectoryPaths |
string[] | Array of directory paths containing PGV parameter files |
RemoteConfigIndexerUrl |
string? | Optional base URL of the Configs service of MA.DataPlatforms.Indexing (see Using Remote Config Indexer). Leave it out, or empty, to search the local directories only. |
Example Configuration#
{
"EssentialsConfig": {
"CfgDirectoryPaths": [
"C:\\Data\\Logging\\AutoConfig",
"C:\\Data\\Logging\\ManualConfig"
],
"PgvDirectoryPaths": [
"C:\\Data\\Parameters\\PGVs",
"C:\\SharedConfigs\\PGVs"
],
"RemoteConfigIndexerUrl": null
}
}
Using Remote Config Indexer#
Use a remote config indexer when many CFG and PGV files are stored centrally and you want Bridge Service to look up where a file is instead of searching its own folders.
RemoteConfigIndexerUrl must point at the Configs service of MA.DataPlatforms.Indexing, which listens on port
5050 by default. It is not the Files service on port 5000. Give the base URL only, with no path, for example
http://config-server.company.com:5050. Bridge Service calls these endpoints on it:
| Endpoint | Used to |
|---|---|
GET /api/processing/files/cfg?configId=… |
Find the CFG files for a config ID |
GET /api/processing/files/pgv?appId=…&appVersion=… |
Find the PGV files for an app ID and version |
GET /api/processing/info?configId=… |
Read the processing info for a config ID |
GET /api/heartbeat |
Check the service is available |
When the indexer doesn't return a file, Bridge Service falls back to searching CfgDirectoryPaths and
PgvDirectoryPaths.
The indexer returns file paths, not file contents
Bridge Service opens the files itself at the paths the indexer returns, so those paths must be readable from where Bridge Service runs:
- Windows: run the indexer on the same machine, or index network share paths that both machines can reach.
- Docker: the paths the indexer reports must exist inside the Bridge Service container. Mount the same storage at the same path in both.
This works the same whether Bridge Service is launched by ADS, run standalone on Windows, or run in Docker.
| AppConfig.json | |
|---|---|
1 2 3 4 5 6 7 | |
5. RdaConfig#
Reduced Data Access (RDA) configuration for reading telemetry data files.
Properties#
| Property | Type | Description |
|---|---|---|
PulFilesSearchPaths |
string[] | Array of directory paths to search for PUL files |
Example Configuration#
{
"RdaConfig": {
"PulFilesSearchPaths": [
"C:\\RDA\\SessionData\\2026",
"C:\\RDA\\Archive",
"\\\\FileServer\\RDA\\Shared"
]
}
}
6. DiskBackedBufferConfig#
Controls the per-session buffer that holds messages pending validation retry. Once a session's
buffer exceeds MaxQueueLength, further items spill to disk instead of growing memory
unbounded, and are read back from disk as the queue drains.
Properties#
| Property | Type | Default | Description |
|---|---|---|---|
MaxQueueLength |
int | 1000 | Number of items kept in memory per session before overflow spills to disk |
TempFolderPath |
string | %TEMP%\EngineeringConversion\DiskBackedBuffer |
Directory used to store the disk-backed overflow files |
Example Configuration#
| AppConfig.json | |
|---|---|
1 2 3 4 5 | |
7. Serilog Configuration#
Bridge Service logging is configured with the Serilog section of the configuration file, in the standard
Serilog JSON settings format. Bridge Service includes
two sinks: Console and File.
Where logs go#
| Your configuration file | Where logs go |
|---|---|
Has a Serilog section |
Only where that section says. -l and LOG_FILE_PATH are ignored. |
Has no Serilog section |
The console, plus a log file that rolls over daily, at the first of: the path given by -l or LOG_FILE_PATH; on Windows, bridge-svc-log.txt in the ADS log file folder; otherwise Logs/bridge-svc-log.txt relative to the folder Bridge Service was started from. |
No log file by default
From Bridge Service 2.1.1, the default configuration file contains a Serilog section that writes to the
console only. No log file is written in any deployment — including when ADS launches Bridge Service, because
the log path ADS passes with -l is ignored while a Serilog section is present. To get a log file, either:
- add a File sink to the
Serilogsection (see Write logs to a file), or - delete the
Serilogsection, so the fallback locations in the table above apply. When launched by ADS, this writesBridgeLog<date>.txtto the ADS log file folder.
Write logs to a file#
Add a File sink next to the Console sink. Use an absolute path: a relative path is resolved from the folder Bridge Service was started from, which for an ADS-launched Bridge Service is its install folder and may not be writable.
| AppConfig.json | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
With "rollingInterval": "Day", the date is added to the file name, for example bridge-svc-log20261014.txt. The
File sink also accepts the standard retainedFileCountLimit and fileSizeLimitBytes arguments to limit disk use.
Docker
Console output appears in docker logs. If you add a File sink, write to a path on a mounted volume, for example
"path": "/logs/bridge-svc-log.txt" with -v /srv/bridge-logs:/logs. Otherwise the log file is lost when the
container is removed.
Log Levels#
Set MinimumLevel.Default to one of:
- Verbose: Very detailed, trace-level information.
- Debug: Debugging information.
- Information: General informational messages (recommended default).
- Warning: Warnings that don't stop operation.
- Error: Errors and exceptions.
- Fatal: Critical failures causing shutdown.
You can also change the level without editing the file, with an
environment variable:
Serilog__MinimumLevel__Default=Debug.
Complete Configuration Example#
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "kafka-prod.company.com:9094",
"PartitionMappings": [],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"InitialisationTimeoutSeconds": 1,
"Domain": "motorsport"
},
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "engine-telemetry" },
{ "AppName": "Chassis*", "Stream": "chassis-telemetry" },
{ "AppName": "Aero*", "Stream": "aerodynamics-telemetry" },
{ "AppName": "*Telemetry", "Stream": "general-telemetry" }
]
},
"BridgeConfig": {
"DataSource": "TestTrack_Simulator",
"UseStringIdentifier": true,
"LiveConcurrencyFactor": 16,
"OffloadConcurrencyFactor": 8,
"AdsTimeoutInSeconds": 600,
"ProcessFlow": "SequentialAll"
},
"EssentialsConfig": {
"CfgDirectoryPaths": [
"C:\\ProgramData\\ATLAS\\Configs",
"\\\\FileServer\\SharedConfigs\\CFG"
],
"PgvDirectoryPaths": [
"C:\\ProgramData\\ATLAS\\Parameters",
"\\\\FileServer\\SharedConfigs\\PGV"
],
"RemoteConfigIndexerUrl": null
},
"RdaConfig": {
"PulFilesSearchPaths": [
"C:\\RDA\\Sessions\\2026",
"\\\\FileServer\\RDA\\Archive"
]
},
"DiskBackedBufferConfig": {
"MaxQueueLength": 1000
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "C:\\Logs\\bridge-service-.txt",
"rollingInterval": "Day",
"retainedFileCountLimit": 30,
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
Troubleshooting#
Common Configuration Issues#
- Issue: Stream API fails to initialize
- Check
BrokerUrlis correct and accessible. - Verify Kafka broker is running.
- Increase
InitialisationTimeoutSeconds.
- Check
- Issue: Data not decoding correctly
- Verify CFG files exist in
CfgDirectoryPaths. - Check PGV files are present in
PgvDirectoryPaths.
- Verify CFG files exist in
- Issue: Stream mapping not working
- Verify
Autois set tofalsewhen using custom mappings. - Check wildcard patterns/order.
- Verify
- Issue: Performance problems
- Increase
LiveConcurrencyFactor/OffloadConcurrencyFactor. - Consider using
ProcessFlow: "DropOldest"if real-time data is more important than completeness.
- Increase
- Issue: Data is being dropped
- Check if
ProcessFlowis set to"DropOldest". This is the expected behavior when buffers are full. - If data completeness is critical, change to
"SequentialAll". - Alternatively, increase
LiveConcurrencyFactorandOffloadConcurrencyFactorto improve throughput.
- Check if
- Issue: Session stops prematurely or doesn't stop
- Adjust
AdsTimeoutInSecondsbased on your data streaming pattern. - Default (720 seconds / 12 minutes) works for most scenarios.
- Reduce for faster timeout detection in live scenarios.
- Increase if you have legitimate gaps in data transmission.
- Adjust
- Issue: Remote Config Indexer not working
- Verify
RemoteConfigIndexerUrlis the base URL of the indexer's Configs service (port 5050 by default), not the Files service, and has no path. - Check network connectivity to the config server, for example by opening
<RemoteConfigIndexerUrl>/api/heartbeat. - Ensure the configuration indexer service is running.
- Check that the file paths the indexer returns are readable from where Bridge Service runs — in Docker, inside the container.
- Add local
CfgDirectoryPathsandPgvDirectoryPathsas backup.
- Verify
- Issue: Bridge Service stops at startup with "DirectoryPaths needs to be specified in EssentialsConfig"
- Outside Windows (for example in Docker) there is no ATLAS 9 fallback: set both
CfgDirectoryPathsandPgvDirectoryPaths, using paths inside the container. - On Windows, set them in
EssentialsConfig, or set the config and PGV folders in ATLAS 9 for the Windows user running Bridge Service.
- Outside Windows (for example in Docker) there is no ATLAS 9 fallback: set both
- Issue: No Bridge Service log file is written
- If the configuration file has a
Serilogsection,-landLOG_FILE_PATHare ignored. Add a File sink to theSerilogsection, or delete the section — see Where logs go.
- If the configuration file has a
- Issue: Changes to
AppConfig.jsonhave no effect when ADS launches Bridge Service- ADS uses
Documents\McLaren Electronic Systems\ATLAS 9\BridgeService\BridgeServiceConfig.jsoninstead. Edit that file — see Choose your deployment.
- ADS uses
- Issue: Stream API fails to connect with a SASL/SSL handshake error
- Verify
ProtocolandMechanismmatch what the broker is actually configured for. - For SASL, double-check
SaslUsername/SaslPassword. - For SSL, verify certificate paths (
SslCaLocation,SslCertificateLocation,SslKeyLocation) are correct and readable by the account running Bridge Service. - Remember
Securityonly activates onceSaslUsername,SslCaLocation, orSslCertificateLocationis set — an incompleteSecurityblock may silently connect unsecured instead of failing.
- Verify
- Issue: Environment variable override isn't applied
- Confirm the key uses
__(double underscore) between each nested segment, e.g.BridgeConfig__DataSource. - Environment variables are only read at startup — restart the Bridge Service after changing one.
- Confirm the key uses
- Issue: Bridge Service fails to start after adding
StandalonePgvList- Each entry must be a plain decimal number or a
0x/0X-prefixed hex number, and fit in the range 0-65535. - Remove or fix any entry that isn't one of those two formats.
- Each entry must be a plain decimal number or a
Resource Requirements
Increasing these values requires more system resources (CPU and memory). Setting values too high on smaller machines may lead to deadlock or threadpool starvation. Recommended settings for an 8-core machine with 16GB RAM:
LiveConcurrencyFactor: 12OffloadConcurrencyFactor: 24