Repository navigation
Conversation
ocelotl
force-pushed
the
docs_exporter_zipkin_json
branch
from
October 30, 2026 22:50
3bc983c to
ab1d108
Compare
…pen-telemetry#5704) * fix(zipkin): tolerate invalid OTEL_EXPORTER_ZIPKIN_TIMEOUT env var Both Zipkin exporters parsed OTEL_EXPORTER_ZIPKIN_TIMEOUT with a bare int() in __init__, so an invalid value (e.g. "10s") raised ValueError during exporter construction and took SDK startup down, unlike the OTLP HTTP/gRPC exporters which warn and fall back to the default. Add _timeout_from_env() in each exporter that skips unset/empty values silently, logs a warning for non-integer values, and falls back to the 10 second default. Explicit timeout argument precedence is unchanged. Assisted-by: Doubao * style(zipkin): inline timeout assignment in both exporters Collapse the two-line timeout resolution into a single assignment per review nit; no behavior change. Assisted-by: Doubao * test(zipkin): patch os.environ in invalid-timeout fallback test Use patch.dict to set OTEL_EXPORTER_ZIPKIN_TIMEOUT instead of assigning os.environ directly, restoring the process environment after the test; applied symmetrically to both exporters. No behavior change. Assisted-by: Doubao * test(zipkin): drop redundant environment restore assertion patch.dict already restores the process environment, so asserting it in the invalid-timeout fallback test adds nothing; remove it from both exporters. No behavior change. Assisted-by: Doubao --------- Co-authored-by: Lukas Hering <40302054+herin049@users.noreply.github.com> Co-authored-by: Leighton Chen <lechen@microsoft.com>
…y#5874) * chore(deps): update dependency pylint to v4 [security] * Fix lint compatibility with Pylint 4 Remove the obsolete suggestion-mode option from both Pylint configs and use NoneType when unwrapping optional annotations. Assisted-by: GPT-6 --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Lukas Hering <lukasheringb@gmail.com> Co-authored-by: Lukas Hering <40302054+herin049@users.noreply.github.com>
ocelotl
force-pushed
the
docs_exporter_zipkin_json
branch
from
November 4, 2026 16:29
d95b105 to
0c51e22
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Documents every hand-written module, class, function and method in
exporter/opentelemetry-exporter-zipkin-json, so that each one carries a docstring, every parameter is documented, and every callable with a return value has aReturns:section.Base branch is
docs-base, a snapshot ofopen-telemetry/opentelemetry-python@3462000f3, so the diff shows only this work. This pull request is against theocelotlfork and is not proposed upstream.What changed
7 files, +592/-22, in 17 commits. The first six document one module each, so each can be read on its own:
27ede05feDocument opentelemetry.exporter.zipkin.json.version714fd2071Document opentelemetry.exporter.zipkin.jsone9b272afeDocument opentelemetry.exporter.zipkin.json.v1d107a8ee9Document opentelemetry.exporter.zipkin.json.v2adfea94dfDocument opentelemetry.exporter.zipkin.encoder5e957ca2bDocument opentelemetry.exporter.zipkin.node_endpointfed63e6d8Render the Zipkin encoder and node endpoint modules in the API referencea56b69bdbCorrect the Zipkin encoder docstrings that misdescribed truncation and endpoint placement68d746303Correct the documented conditions for dropping a tag and replacing the service nameab1d10890Document the AttributeError in the parent id helper and the per-batch service name replacementf4a60241cState the truncation condition, the parent id None case and the v1 endpoint placement86ebf33efRecord the KeyError on a resource with no service name, and fix two scope claimsb8cbc671dBound the scope bypass claim to v2 and document the timeout parsing failurefcb6da40dBound the integer address spelling and two Raises conditionsdc0f676a5Render the v1 and v2 JSON encoder modules in the API reference1763ea8f1Name the full escape rule, the empty endpoint variable and the missing parent attributed95b10571Document the AttributeError an event with no attributes producesThe whole package is hand-written. None of its 6 source files matches the generated-file rules, so all 6 are in scope.
Every commit after
fed63e6d8corrects docstrings whose claims did not match the code, each one found by running the code the docstring describes.a56b69bdbfixes the claim that the v1 truncation of scope, status and dropped count tags is a no-op, the claim that the endpoint always becomeslocalEndpoint, and the silence about the v1TypeErroron the renderedZipkinExporterpage.68d746303fixes the condition under which a sequence tag is dropped and the claim that the service name is replaced only once.ab1d10890records theAttributeErrorthatEncoder._get_parent_idraises for a rootSpan, and restates the service name replacement onZipkinExporter.exportto match.f4a60241cadds the positive-limit condition to the v1 truncation sentence, drops the unreachableSpanContextcase from theEncoder._get_parent_idreturn description, and names the binary annotations alongside the annotations as the place the v1 encoder writes the local endpoint.86ebf33efrecords theKeyErrorboth constructors raise when the globally registered tracer provider carries a resource with noservice.name, replaces a scope example thatTracerProvider.get_tracercannot produce, and adds the non-empty condition to the service name overwrite.b8cbc671dbounds the scope truncation bypass to v2, sinceV1Encoder._extract_binary_annotationscuts the same value again, and records theValueErrora non-integerOTEL_EXPORTER_ZIPKIN_TIMEOUTraises out of the constructor.fcb6da40dbounds the integer spelling of an IPv6 address, sinceipaddress.ip_addressreads an integer below2**32as IPv4, and adds the missing condition to twoRaises:entries.1763ea8f1adds control characters to the list of characters that beat the running-length count, qualifies theOTEL_EXPORTER_ZIPKIN_ENDPOINTfallback for an empty value, and namesNonRecordingSpan, which has noparentattribute at all.d95b10571records theAttributeErroranopentelemetry.sdk.trace.Eventbuilt without attributes produces, whichSpan.add_eventnever does.fed63e6d8anddc0f676a5are the only changes outside the package, both todocs/exporter/zipkin/zipkin.rst, which previously renderedopentelemetry.exporter.zipkin.jsonand nothing else from this distribution.Moving the
ZipkinExporterconstructor parameters onto the class docstring madesphinx_autodoc_typehintsemit the type of theversionparameter, andopentelemetry.exporter.zipkin.encoder.Protocolhad no page to resolve to, which thenitpickybuild reported.fed63e6d8addsautomoduledirectives foropentelemetry.exporter.zipkin.encoderandopentelemetry.exporter.zipkin.node_endpoint, which documentsProtocol, makes the reference resolve, and puts the newEncoder,JsonEncoderandNodeEndpointdocstrings in the API reference, where they were previously invisible.dc0f676a5adds the same directives foropentelemetry.exporter.zipkin.json.v1andopentelemetry.exporter.zipkin.json.v2. TheJsonEncoderdocstring tells the reader that_encode_spanis supplied byJsonV1EncoderandJsonV2Encoder, and neither class had a page to reach, so the newV1Encoder,JsonV1EncoderandJsonV2Encoderdocstrings appeared nowhere in the built documentation.automoduleskips imported names unless:imported-members:is given, so the two blocks add no duplicate object description, and the built page carries no duplicate HTMLidand no dangling internal anchor.Conventions followed
docs/conf.pydoes not setspecial-members, so an__init__docstring never renders. Constructor parameters therefore go on the class docstring, which is what the API reference shows, and__init__carries a short docstring saying so. That keeps one parameter list that cannot drift out of step with a second copy. This moved theZipkinExporterparameters off__init__, and addedArgs:sections toEncoder,JsonEncoder,V1EncoderandJsonV2Encoder, which inherit themax_tag_value_lengthconstructor parameter.The
ZipkinExporterArgs:block previously ended with an unlabelled paragraph about the(local_node_ipv4, local_node_ipv6, local_node_port)tuple, indented as though it were part of the parameter list. It is now prose on the class docstring, above theArgs:section, where napoleon renders it as prose.Cross-references are written as inline literals in double backticks rather than as
:class:roles wherever the target has no autodoc page, sincedocs/conf.py:102setsnitpicky = Trueandtox -e docspasses-W.Verification
Docstring coverage over
exporter/opentelemetry-exporter-zipkin-json/src, measured by walking the AST: 0 remaining gaps, down from 34. The 34 broke down as 1 missing module docstring, 3 missing class docstrings, 26 missing function or method docstrings, 2 callables with undocumented parameters and 2 callables with noReturns:section.ruff checkandruff format --checkwith ruff 0.16.1, the version pinned indev-requirements.txt:23: pass on all 6 files.tox -e py312-test-opentelemetry-exporter-zipkin-json: 53 passed.tox -e lint-opentelemetry-exporter-zipkin-json: 10.00/10, no messages. No# pylint: disable=pragma was added.tox -e docs, which runssphinx-build -Wwithnitpicky = Trueset atdocs/conf.py:102: 16 warnings, the same 16 as the base, of the same four kinds. All 16 are inopentelemetry-apiandopentelemetry-exporter-otlp-proto-http, neither of which this branch touches:Without the
fed63e6d8repair the count was 17, the extra one beingpy:class reference target not found: opentelemetry.exporter.zipkin.encoder.Protocol.Things to decide
A real bug, documented but deliberately not fixed
exporter/opentelemetry-exporter-zipkin-json/src/opentelemetry/exporter/zipkin/json/v1/__init__.py:59readsif isinstance(tag_value, str) and self.max_tag_value_length > 0:. It does not guard againstmax_tag_value_lengthbeingNone, which is exactly whatZipkinExporter.__init__passes on when its ownmax_tag_value_lengthargument is left unset. Every sibling comparison inopentelemetry/exporter/zipkin/encoder/__init__.pywritesself.max_tag_value_length is not None and self.max_tag_value_length > 0.The effect is that
ZipkinExporter(version=Protocol.V1)raisesTypeError: '>' not supported between instances of 'NoneType' and 'int'on the first export of any span that contributes a tag. A span always contributes tags, because the resource always carriestelemetry.sdk.*attributes, so the v1 protocol is unusable at its default configuration. Reproduced on this branch:This is a documentation change, so the behaviour is left alone and the documentation describes it instead: the
max_tag_value_lengthentry on theZipkinExporterclass docstring, aRaises:block onZipkinExporter.export, andRaises:blocks onV1Encoder._extract_binary_annotationsandJsonV1Encoder._encode_span. It deserves its own issue and its own fix.Seven further defects, also documented rather than fixed
Each one was found by running the code the docstring describes, and each one is recorded in the docstring of the callable that carries it rather than repaired. Every path and line number below was read off the head of this branch.
src/opentelemetry/exporter/zipkin/encoder/__init__.py:201_get_parent_idreadsspan_context.parent.span_idon itsSpanbranch without checking thatparentis set, so a rootSpanraisesAttributeError: 'NoneType' object has no attribute 'span_id'and aNonRecordingSpan, which has noparentattribute at all, raisesAttributeError: 'NonRecordingSpan' object has no attribute 'parent'. Both encoders passspan.parent, so the exporter never reaches it.Raises:block ofEncoder._get_parent_idsrc/opentelemetry/exporter/zipkin/node_endpoint.py:83resource.attributes[SERVICE_NAME]is a plain subscript, soNodeEndpoint()andZipkinExporter()both raiseKeyError: 'service.name'when the globally registered tracer provider carries a resource without that attribute, whichTracerProvider(resource=Resource.get_empty())produces.Raises:blocks ofNodeEndpointandZipkinExportersrc/opentelemetry/exporter/zipkin/json/__init__.py:166OTEL_EXPORTER_ZIPKIN_TIMEOUTgoes straight toint, so a variable holding10sor the empty string raisesValueErrorout of the constructor instead of falling back to 10 seconds.timeoutentry and theRaises:block ofZipkinExportersrc/opentelemetry/exporter/zipkin/encoder/__init__.py:307_extract_tag_value_string_from_sequencecountslen(str(element))beforejson.dumpsescapes anything, so an element holding a non-ASCII character, a quote, a backslash or a control character makes the rendered array exceedmax_tag_value_length. The caller then cuts it mid-escape:JsonV2Encoder(9)on["\n\n\n\n\n"]yields a tag value thatjson.loadsrejects._extract_tag_value_string_from_sequencesrc/opentelemetry/exporter/zipkin/encoder/__init__.py:411_extract_annotations_from_eventsreadsevent.attributes.items()without guarding, andopentelemetry.sdk.trace.EventdefaultsattributestoNone, so anEventbuilt directly without attributes raisesAttributeError.Span.add_eventstores an empty mapping, so a span recorded through the SDK never reaches it.Raises:block of_extract_annotations_from_eventssrc/opentelemetry/exporter/zipkin/node_endpoint.py:153ipaddress.ip_addressreads an integer by its magnitude, so an IPv6 address given as an integer below2**32parses as IPv4 and theipv6setter rejects it.NodeEndpoint(ipv6=1), which is::1, raisesValueError.IpInputdocstring and theipv6settersrc/opentelemetry/exporter/zipkin/json/__init__.py:161-164self.encoderis assigned only forProtocol.V1andProtocol.V2, so any otherversionmakes the next line raiseAttributeError: 'ZipkinExporter' object has no attribute 'encoder'. The parameter is annotatedProtocolandProtocolhas only those two members, so no well-typed call reaches it.All paths in the table are relative to
exporter/opentelemetry-exporter-zipkin-json.Bad documentation in a neighbouring package, left alone
exporter/opentelemetry-exporter-zipkin-proto-http/src/opentelemetry/exporter/zipkin/proto/http/__init__.pydocuments aversionparameter in theArgs:section ofZipkinExporter.__init__that its signature does not have. That package is outside the scope of this pull request, so it was not touched.