Turning Ericsson Cell Trace files into analysis-ready CSV
A dependency-free Python decoder for the stable framing and common headers inside Ericsson Cell Trace files.
- Telecom
- Python
- Data
Loading post…
A dependency-free Python decoder for the stable framing and common headers inside Ericsson Cell Trace files.
Loading post…
Ericsson Cell Trace files contain useful radio events, but the raw .bin.gz format is
awkward when the next step is analysis in DuckDB, pandas, or a spreadsheet. I built
ericsson-celltrace-decoder
to extract the stable, byte-aligned parts into named CSV columns without requiring an
ENM installation.
The library is pure Python standard library and works as either a CLI or an imported iterator.
The file is a sequence of length-prefixed records. Each record begins with a big-endian 16-bit length and 16-bit type:
flowchart TD H[File header] --> S[Scanner connection] S --> E1[Event] E1 --> E2[Event] E2 --> EN[More events] EN --> F[Footer]
The decoder walks record types 0, 3, 4, and 5: file header, scanner connection, event, and footer. For events, it decodes the common 32-byte header, including the timestamp, scanner and module IDs, global cell ID, S1AP IDs, GUMMEI, radio UE reference, and trace session reference.
That shared header is enough to answer many operational questions without pretending to understand every event payload.
Fields after the common header are bit-packed and depend on the event catalog for the
specific Ericsson software release. Those proprietary event_*.asn definitions are
not bundled with the project.
Instead of guessing, the decoder writes the remaining bytes as payload_hex. A
downstream decoder with the correct release catalog can interpret them later. This
boundary is deliberate: partial decoding is useful; silently assigning the wrong
schema is worse than leaving bytes explicit.
git clone https://github.com/echo-cool/ericsson-celltrace-decoder.git
cd ericsson-celltrace-decoder
python -m pip install -e .
celltrace-decode trace.bin.gz -o decoded.csv --meta
A directory can be decoded in one pass, and filters keep only relevant event IDs or cells:
celltrace-decode CellTrace/ -O decoded_csv/
celltrace-decode CellTrace/ -O traffic/ --event-id 3076
celltrace-decode CellTrace/ -O one_cell/ --cell LMTR485Z
The same parser can stream records in Python:
from celltrace_decoder import decode_file
for record in decode_file("trace.bin.gz"):
if record.get("rec_type") == 4 and record["event_id"] == 3076:
print(record["ts"], record["cell_name"], record["payload_hex"][:64])
The global cell ID carries an eNB component and a sector byte. The decoder combines that sector with the file's network-element label to produce the managed-object cell name used by the surrounding performance data. The sector mapping is configurable for operators with different naming conventions.
I validated the record walker against 91 production files containing 2,030,203 events. It reached the footer with zero unparsed bytes. That confirms the framing and byte coverage for the reference data; it does not claim that every vendor release or per-event payload has been decoded.
The useful design lesson was to separate trustworthy structure from release-specific detail. Once the stable envelope is in CSV, event inventory, cell filtering, time correlation, and targeted payload work become much easier.
Comments
View on GitHub