Closed justfalter closed 4 months ago
Two issues with your data:
1) The input file is expected to be a single JSON object:
{
"resourceSpans": ...
}
You have multiple objects (one per line) which do not have an equivalent representation in OTLP data types (it would be an array of TraceData
object). It sounds like a problem worth solving.
2) All the trace/span IDs in the JSON are empty strings, which are not valid. So even if the structure was correct (you can try submitting just one line of that file), I suspect the parsing will then choke on the IDs.
- The input file is expected to be a single JSON object:
The implementation expects it to be a single JSON object, but the specification linked to by the origin feature request (#4949) states that the file is supposed to be in "JSON lines" format.
JSON lines file This file is a JSON lines file (jsonlines.org), and therefore follows those requirements:
- UTF-8 encoding
- Each line is a valid JSON value
- The line separator is \n
- The preferred file extension is jsonl
When I use the current file-exporter (https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.96.0), it generates a file in "JSON lines" format.
- All the trace/span IDs in the JSON are empty strings, which are not valid. So even if the structure was correct (you can try submitting just one line of that file), I suspect the parsing will then choke on the IDs.
In order to avoid this as a distraction, I'm including a trace that I've generated using opentelemetry's js SDK.
The opentelemetry collector contrib configuration:
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
processors:
batch:
# The following ensures that one span is written per line.
send_batch_size: 1
send_batch_max_size: 1
exporters:
file:
path: /output/otel.json
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [file]
The generated trace otel.json. Note that there are 4 liness, one JSON object per line.
I can use the following jq to process the file into a single JSON object. The following concatenates all of the .resourceSpans
arrays across each JSON object (per line), adding them to a single JSON object that Jaeger currently expects:
jq -c --slurp '{resourceSpans: map(.resourceSpans[])}' < otel.json > otel-out.json
Which gives me otel-out.json.
My expectation is that if Jaeger says that it will import OpenTelemetry JSON generated by the opentelemetry collector's file-export, then it should be able to handle a multi-line JSON file.
A initial proposal: what if we get the frontend to add a []
and commas in between these json objects and loop over them with the same existing logic. Would this be a viable solution?
@yurishkuro Any guidance on fixing it will be more helpful
I will move to UI
The current code that checks for OTLP format is here: https://github.com/jaegertracing/jaeger-ui/blob/d47fb0938a93cc468b89ffe6ee1feb7749804977/packages/jaeger-ui/src/utils/readJsonFile.tsx#L27
It effectively checks for JSON like {"resourceSpans":[...]}
. I would suggest extending that code to:
[{"resourceSpans":[arr1]}, ... {"resourceSpans":[arrN]}]
resourceSpans
arrays into a single {"resourceSpans":[arr1..., arrN]}
which then should be handled normally by the existing codeI need this too. For now, I'm using a script like this that allows me to send all traces from a local file to Jagear.
import requests
import json
import argparse
from pathlib import Path
def send_post_request(url, json_data):
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(json_data), headers=headers)
response.raise_for_status()
return response
def process_file(input_file: Path, server_url: str):
lines = input_file.read_text().splitlines()
api_url = server_url.rstrip("/") + "/v1/traces"
for line in lines:
json_data = json.loads(line.strip())
send_post_request(api_url, json_data)
print("Finished")
def main():
parser = argparse.ArgumentParser(description="Send saves traces to OLTP collector")
parser.add_argument(
'--server-url',
type=str,
default='http://localhost:4318',
help="The server URL to send the POST requests to."
)
parser.add_argument('input_file', type=Path, help="The JSONL file to be processed.")
args = parser.parse_args()
process_file(args.input_file, args.server_url)
if __name__ == "__main__":
main()
@sfc-gh-kbregula if you're proficient in JS consider if you can bring https://github.com/jaegertracing/jaeger-ui/pull/2254 over the finish line.
@yurishkuro I will take this up.
Lately I have searching this issue in Jaeger. But moved here 😅
What happened?
jaegertracing/all-in-one 1.55 fails to import JSON generated by OTEL File Exporter.
Steps to reproduce
test.json
test.json
onto Jaeger'sClick or drag files to this area.
Expected behavior
I expect Jaeger to have loaded successfully loaded the Open Telemetry traces, per https://github.com/jaegertracing/jaeger/issues/4949
Relevant log output
No response
Screenshot
Additional context
The existing code only expects there to be a single JSON object entry in the OTEL File Exporter JSON output, but the file exporter specification says that the is in JSON lines format (file contains multiple JSON serialized objects, with a new-line separating each).
This is evident when looking at the test data in the original PR, as it is only a single JSON object entry. https://github.com/jaegertracing/jaeger/pull/5155/files
Jaeger backend version
1.55
SDK
No response
Pipeline
Example of the opentelemetry collector configuration I use to capture OTEL traces to OTEL file-exporter format:
Stogage backend
No response
Operating system
No response
Deployment model
No response
Deployment configs
No response