When I switch to Spring Boot 3.x + Micrometer, the quartz jobs Observability stop working.

Here is a simple example, how my Job looks like:

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

@DisallowConcurrentExecution
public class QueueJob implements Job {

  private final QueueService queueService;

  @Override
  public void execute(JobExecutionContext context) {
    queueService.fetchAndSaveQueues();
  }
}

There was TracingJobListener.java in Spring Sleuth. According to this class I have written my own:

import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.propagation.Propagator;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.TriggerListener;


public class TracingJobListener implements JobListener, TriggerListener {

  static final String TRIGGER_TAG_KEY = "quartz.trigger";

  static final String CONTEXT_SPAN_KEY = Span.class.getName();

  static final String CONTEXT_SPAN_IN_SCOPE_KEY = Tracer.SpanInScope.class.getName();

  private static final Propagator.Getter<JobDataMap> GETTER = (carrier, key) -> {
    Object value = carrier.get(key);
    if (value instanceof String) {
      return (String) value;
    }
    return null;
  };

  private final Tracer tracer;

  private final Propagator propagator;

  public TracingJobListener(Tracer tracer, Propagator propagator) {
    this.tracer = tracer;
    this.propagator = propagator;
  }

  @Override
  public String getName() {
    return getClass().getName();
  }

  @Override
  public void triggerFired(Trigger trigger, JobExecutionContext context) {
    Span nextSpan = propagator.extract(context.getMergedJobDataMap(), GETTER).start();
    Span span = nextSpan.name(context.getTrigger().getJobKey().toString()).tag(TRIGGER_TAG_KEY,
        context.getTrigger().getKey().toString());
    context.put(CONTEXT_SPAN_KEY, span);
    context.put(CONTEXT_SPAN_IN_SCOPE_KEY, tracer.withSpan(span.start()));
  }

  @Override
  public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
    return false;
  }

  @Override
  public void triggerMisfired(Trigger trigger) {

  }

  @Override
  public void triggerComplete(Trigger trigger, JobExecutionContext context,
      CompletedExecutionInstruction triggerInstructionCode) {
    closeTrace(context);
  }

  @Override
  public void jobToBeExecuted(JobExecutionContext context) {

  }

  @Override
  public void jobExecutionVetoed(JobExecutionContext context) {
    closeTrace(context);
  }

  @Override
  public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
  }

  private void closeTrace(JobExecutionContext context) {
    Object spanInScope = context.get(CONTEXT_SPAN_IN_SCOPE_KEY);
    Object span = context.get(CONTEXT_SPAN_KEY);
    if (spanInScope instanceof Tracer.SpanInScope) {
      ((Tracer.SpanInScope) spanInScope).close();
    }
    if (span instanceof Span) {
      ((Span) span).end();
    }
  }
}

@bclozel what do you think is it worth a PR or does somebody is working on a same thing yet?

Comment From: bclozel

@jmecsei I think this would be a generally useful addition for all quartz users, not just Spring Framework. In fact, the class you've shared doesn't have any dependency on Spring Framework.

I think this could be reworked to only depend on the Observation API (so only the io.micrometer:micrometer-observation module) and contributed to the quartz project. In my opinion, the right approach is to contribute the observability instrumentation as close as possible to the actual project, where the experts are.

What do you think?

Comment From: jmecsei

Yes I think so, it should be in the quartz project, but as I see the quartz's github pages it is fairly dead project. This is why I think we can put it to the Spring Framework, thus nobody miss functionality what is existed in previously.

Comment From: bclozel

Spring Framework's Quartz support is itself stale at the moment. I'm not sure we want to invest there given the situation. Let me discuss this with the team.

Comment From: bclozel

Declining for the reasons listed above.