Skip to content

Conversation

@TomasLongo
Copy link
Contributor

Description

This PR adds an HTTP-Service to the OtelLogsSource, which runs alongside the gRPC-Service under a separate endpoint.

Both Services share the same underlying Armeria-Server, running under the same port.

Breakdown

The PR is kind of heavy. The OtelLogsSource had to be restructured resulting in the refactoring of the present tests.

A quick breakdown of the changes will certainly help with the review

One Server, two services

OtelLogsSource is now inhabitetd by two services running under different paths behind the same port.
The path of the services can be configured by the two fields path and http_path

  • path is the already present field for configuring path of the grpc service and keeps its purpose
  • http_path will set the path for the new http service

Unframed Requests

Since unframed requests served the purpose of sending plain http requests to the grpc server, this functionality has been dropped. However, for backwardscompatibilty of the config, it is still present in the config data structure.

CreateServer

The class CreateServer deals with creating both, http and gRPC servers. However, in its current form, the intended use is to create a server with a single service. Two quick attempts to rewrite the Class for the purpose if this PR yielded no results.

So the final version of the server creation loosely resembles the functionality found in CreateServer.

Refactoring of tests

Many tests were making sure that the former gRPC server, with unframed requests enabled, would handle http requests correctly. I have dropped this tests completely, replacing them with a separate test class that handles tests regarding the http functionality. I added a few improvements along the way like

  • Getting rid of unnecessary mocks
  • Introducing parameterized tests
  • Using unified test data and fixtures

Decisions made and additional considerations

Getting completely rid of unframed requests

enable_unframed_requests has no effect any more, since its purpose has been replaced with the new http service

Configuration

A new field, http_path has been added to specify the path of the http service. However, one could extend the config to

  • enable the client to specify only on of both service by omitting one of both paths. Currently, both services will be instantiated.

CreateServer

I think that the intention of CreateServer, to provide a unified mechanism to bootstrap armeria servers, is absolutely the right thing todo. However, in its current form, it only supports creating servers with a single service.

It's worth thinking about how to refactor CreateServer to streamline server creation for future plugins. The challenge I encountered was how to best model the fact, that different services might need different server capabilities/configurations.

Figuring this out, would have gone well beyond the scope of this PR.

Issues Resolved

Resolves #[Issue number to be closed when this PR is merged]

Check List

  • New functionality includes testing.
  • New functionality has a documentation issue. Please link to it in this PR.
    • New functionality has javadoc added
  • Commits are signed with a real name per the DCO

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Signed-off-by: Tomas Longo <[email protected]>
Signed-off-by: Tomas Longo <[email protected]>
Signed-off-by: Tomas Longo <[email protected]>
Signed-off-by: Tomas Longo <[email protected]>
Signed-off-by: Tomas Longo <[email protected]>
Signed-off-by: Tomas Longo <[email protected]>
@TomasLongo
Copy link
Contributor Author

@KarstenSchnitter

Copy link
Collaborator

@KarstenSchnitter KarstenSchnitter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a start of a review. Can you check the tests for unused imports. This is failing the CI builds. I need more time for the review. Please expect more comments to come.

// no path provided. Will be set by config.
@Post("")
@Consumes(value = "application/json")
public ExportTraceServiceResponse exportLog(ExportLogsServiceRequest request) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this returning ExportTraceServiceResponse? Shouldn't this return a ExportLogServiceResponse?

Copy link
Contributor Author

@TomasLongo TomasLongo Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I copied the Http-Service from the Trace-Source. This is the remnant from it. Fix is pushed.

@TomasLongo TomasLongo force-pushed the otel-logs-source-http-service branch 2 times, most recently from 3cf2c0f to 1dd14dd Compare November 10, 2025 12:01
@TomasLongo TomasLongo force-pushed the otel-logs-source-http-service branch from 1dd14dd to 965b93d Compare November 14, 2025 07:18
Copy link
Collaborator

@KarstenSchnitter KarstenSchnitter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already have some comments. I still need to review the tests.

try {
logs = oTelProtoDecoder.parseExportLogsServiceRequest(request, Instant.now());
} catch (Exception e) {
LOG.error("Failed to parse the request {} due to:", request, e);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use warning level and sensitive request marker.

Suggested change
LOG.error("Failed to parse the request {} due to:", request, e);
LOG.warn(DataPrepperMarkers.SENSITIVE, "Failed to parse request with error '{}'. Request body: {}.", e.getMessage(), request);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Is this a general rule? Use WARN-level with SENSITIVE-Marker for errors?

Is there any documentation on how to logging should be done in DataPrepper? Could not find any in the README

throw new BadRequestException(e.getMessage(), e);
}

final List<Record<Object>> records = logs.stream().map(log -> new Record<Object>(log)).collect(Collectors.toList());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These records are only required in the else block of the following condition. Please move this operation to this block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


if (oTelLogsSourceConfig.hasHealthCheck()) {
LOG.info("HTTP source health check is enabled");
serverBuilder.service("/health", HealthCheckService.builder().longPolling(0).build());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please extract the String to a constant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

serverBuilder.maxRequestLength(oTelLogsSourceConfig.getMaxRequestLength().getBytes());
}
final int threadCount = oTelLogsSourceConfig.getThreadCount();
serverBuilder.blockingTaskExecutor(new ScheduledThreadPoolExecutor(threadCount), true);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the same logic as in CreateServer to configure the task executor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@TomasLongo TomasLongo force-pushed the otel-logs-source-http-service branch from e05da93 to 656475c Compare November 21, 2025 08:27
Copy link
Collaborator

@KarstenSchnitter KarstenSchnitter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good so far. I would like to see an end-to-end test with OTLP/HTTP if possible. Can you add it? Please promote this PR to ready for review.

@TomasLongo please also fix the unused imports in the tests that lead to the failing Gradle builds.

@TomasLongo
Copy link
Contributor Author

Yes. I'll add an E2E Test.

Signed-off-by: Tomas Longo <[email protected]>
@TomasLongo TomasLongo force-pushed the otel-logs-source-http-service branch from f6c5b40 to 5f2aeb3 Compare November 26, 2025 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants