Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can a single MetricsLogger be used in different threads which will use different dimensions? (E.g. in a request handler) #131

Open
kerling opened this issue Jan 13, 2023 · 1 comment
Labels
question Further information is requested

Comments

@kerling
Copy link

kerling commented Jan 13, 2023

Hey all,

Thanks for the library! This has sped up telemetry work quite a bit on a new service I'm working on.

Can I use a single MetricsLogger in different threads of a service, with each thread using different dimensions?

E.g. can I use a single MetricsLogger bean in an ECS service, which is expected to handle multiple requests concurrently? I would use it to log metrics for downstream service calls and setting specific downstream APIs as the dimension for each call, like:

  • Namespace: OtherTeamService, Endpoint (dimension): GetSomeEntity, Latency (metric): 100ms
  • Namespace: OtherTeamService, Endpoint (dimension): PutSomeEntity, Latency (metric): 500ms
  • Namespace: OtherTeamService, Endpoint (dimension): PostSomeOperation, Latency (metric): 1000ms

Can I use an implementation like...

@AllArgsConstructor
@RestController
public class MyApiHandler {
    private final MetricsLogger metricsLogger; // This is a singleton bean which is passed in through the constructor
    private final OtherTeamServiceClient otherTeamServiceClient;

    @GET
    @Path("myApi")
    public MyApiHandlerResponse handleRequest(final MyApiHandlerRequest request) {
        // [...]
        metricsLogger.setDimensions(DimensionSet.of("Endpoint", "GetSomeEntity");
        metricsLogger.putMetric("Latency", Duration.between(getSomeEntityStart, getSomeEntityEnd).toMillis(), Unit.MILLISECONDS);
        metricsLogger.flush()
        // [...]
        metricsLogger.setDimensions(DimensionSet.of("Endpoint", "PutSomeEntity");
        metricsLogger.putMetric("Latency", Duration.between(putSomeEntityStart, putSomeEntityEnd).toMillis(), Unit.MILLISECONDS);
        metricsLogger.flush()
        // [...]
        metricsLogger.setDimensions(DimensionSet.of("Endpoint", "PostSomeOperation");
        metricsLogger.putMetric("Latency", Duration.between(postSomeOperationStart, postSomeOperationEnd).toMillis(), Unit.MILLISECONDS);
        metricsLogger.flush()
    }
}

...knowing that there will be potentially hundreds of concurrent requests to the same handler on the same ECS instance? Or would the multiple concurrent calls to .setDimension across the threads step on each other's toes?

@gordonpn
Copy link
Member

If the order of operations aren't guaranteed, then you may end up with mixed up dimensions.

For example if PutAPI starts, sets Put dimensions, does not flush yet. GetAPI starts, sets Get dimensions (effectively overwriting the Put dimensions). PutAPI flushes with Get dimensions and GetAPI follows and flushes with Get dimensions as well.

@markkuhn markkuhn added the question Further information is requested label Oct 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants