Ryan Whitcomb
Ryan Whitcomb

Reputation: 3

How do I setup baggage fields in Spring Cloud Sleuth for a Command Line Runner?

I'm successfully using Spring Cloud Sleuth in a Spring Boot microservice and am having fields logged and sent over http headers appropriately.

I now need to integrate this same process for logging and header propagation in a Spring Boot command line runner application but it looks like no trace and span are automatically setup since it isn't in the middle of an Http request (as it is a command line app). I cannot see these fields in my logs (with the same %X format in log configuration).

I've looked at the docs and can't find any examples for this specific use case. Is this possible in a command line runner app?

Upvotes: 0

Views: 1851

Answers (1)

Plamen
Plamen

Reputation: 106

In order to add baggage you need to have a span. Spring Cloud Sleuth and Spring Boot create a span for you when the controller is invoked. If you want to do the same using CLI application, you need to create span yourself.

You have two options.

Using API calls:

Span span = this.tracer.nextSpan().name("mySpan");
// do some work
span.end(); // best to put it in finally to make sure span is always ended

Or you can use annotations:

@NewSpan
public void doWork() {
}

If you use the annotation, please keep in mind the AOP proxies limitations. In particular self invocations (calls using this) would not work.

@SpringBootApplication
public class ConsoleApplication 
  implements CommandLineRunner {

    @Override
    public void run(String... args) {
        doWork(); //this is the same as this.doWork();
    }

    @NewSpan
    public void doWork() {
    }
}

This is not going to work as doWork is not invoked through the AOP proxy. Make sure that you annotate a component managed by Spring and then use an injected instance.

@SpringBootApplication
public class ConsoleApplication 
  implements CommandLineRunner {

    @Autowired
    private MyService myService;

    @Override
    public void run(String... args) {
        myService.doWork();
    }

}

@Component
class MyService {

    @NewSpan
    public void doWork() {
    }

}

In this case myService is not instance of MyService, but rather an instrumented proxy.

Upvotes: 2

Related Questions