Skip to content

Commit

Permalink
Return empty receivers list if tracing backend isn't connected (#338)
Browse files Browse the repository at this point in the history
* fix(tracing): Return empty receivers list if tracing backend isn't connected

* Comment on tracing config limitations
  • Loading branch information
mmkay authored Dec 20, 2024
1 parent e6a53ab commit a2f5522
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
13 changes: 12 additions & 1 deletion src/grafana_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,15 @@ def _requested_tracing_protocols(self) -> Set[ReceiverProtocol]:
)

def _update_tracing_provider(self):
# If the "upstream" tracing is not ready, we don't want to publish the receivers.
# Otherwise, charms that integrate over `tracing` would start sending traces to an endpoint that isn't open.
requested_tracing_protocols = (
self._requested_tracing_protocols if self._tracing.is_ready() else []
)
self._tracing_provider.publish_receivers(
tuple(
(protocol, self._get_tracing_receiver_url(protocol))
for protocol in self._requested_tracing_protocols
for protocol in requested_tracing_protocols
)
)

Expand Down Expand Up @@ -880,6 +885,12 @@ def _tracing_receivers(self) -> Dict[str, Union[Any, List[Any]]]:
Returns:
a dict with the receivers config.
"""
if not self._tracing.is_ready():
logger.warning(
"Tracing backend is not connected yet: grafana-agent cannot ingest traces."
)
return {}

receivers_set = self._requested_tracing_protocols

if not receivers_set:
Expand Down
35 changes: 33 additions & 2 deletions tests/scenario/test_tracing_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,37 @@ def base_state():


def test_tracing_relation(ctx, base_state):
# GIVEN a tracing relation over the tracing-provider endpoint
tracing_provider = Relation(
"tracing-provider",
remote_app_data=TracingRequirerAppData(receivers=["otlp_http", "otlp_grpc"]).dump(),
)
tracing = Relation(
"tracing",
remote_app_data=TracingProviderAppData(
receivers=[
Receiver(protocol={"name": "otlp_grpc", "type": "grpc"}, url="http:foo.com:1111")
]
).dump(),
)

state = dataclasses.replace(base_state, relations=[tracing, tracing_provider])
# WHEN we process any setup event for the relation
state_out = ctx.run(ctx.on.relation_changed(tracing_provider), state)

agent = state_out.get_container("agent")

# THEN the agent has started
assert agent.services["agent"].is_running()
# AND the grafana agent config has a traces config section
fs = agent.get_filesystem(ctx)
gagent_config = fs.joinpath(*CONFIG_PATH.strip("/").split("/"))
assert gagent_config.exists()
yml = yaml.safe_load(gagent_config.read_text())
assert yml["traces"]["configs"][0], yml.get("traces", "<no traces config>")


def test_tracing_provider_without_tracing(ctx, base_state):
# GIVEN a tracing relation over the tracing-provider endpoint
tracing = Relation(
"tracing-provider",
Expand All @@ -53,12 +84,12 @@ def test_tracing_relation(ctx, base_state):

# THEN the agent has started
assert agent.services["agent"].is_running()
# AND the grafana agent config has a traces config section
# AND the grafana agent config has an empty traces config section
fs = agent.get_filesystem(ctx)
gagent_config = fs.joinpath(*CONFIG_PATH.strip("/").split("/"))
assert gagent_config.exists()
yml = yaml.safe_load(gagent_config.read_text())
assert yml["traces"]["configs"][0], yml.get("traces", "<no traces config>")
assert yml["traces"] == {}


def test_tracing_relations_in_and_out(ctx, base_state):
Expand Down

0 comments on commit a2f5522

Please sign in to comment.