001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.server.tracing; 018 019/** 020 * Handle to one in-flight {@link TracerHook}-managed span. 021 * 022 * <p> 023 * Returned by {@link TracerHook#startSpan(org.apache.juneau.rest.server.RestRequest)}. The framework drives 024 * the {@code setStatusCode} / {@code setError} / {@code close} transitions inside a {@code finally} 025 * block so the span always closes — including on exception paths. 026 * 027 * <p> 028 * Bridge implementations typically wrap the downstream tracer's native span / scope. The OpenTelemetry 029 * bridge in {@code juneau-rest-server-tracing-otel}, for example, wraps an 030 * {@code io.opentelemetry.api.trace.Span} plus its {@code io.opentelemetry.context.Scope}: setters 031 * translate to span attribute / status writes; {@code close()} ends the span and closes the OTel 032 * scope. 033 * 034 * @since 10.0.0 035 */ 036public interface Scope extends AutoCloseable { 037 038 /** 039 * Records the HTTP response status code on the span. 040 * 041 * <p> 042 * Called by the framework after the {@code @RestOp} handler completes — before 043 * {@link #close()}, and before {@link #setError(Throwable)} if the handler also threw. Bridges 044 * typically translate the status into both a numeric attribute (e.g. OpenTelemetry's 045 * {@code http.response.status_code}) and an overall span status (HTTP {@code 5xx} maps to 046 * span-status {@code ERROR}; other codes map to {@code UNSET} per the OTel HTTP semantic 047 * conventions). 048 * 049 * @param statusCode The HTTP status code (e.g. {@code 200}, {@code 404}, {@code 500}). 050 */ 051 void setStatusCode(int statusCode); 052 053 /** 054 * Records the exception (if any) the {@code @RestOp} handler threw on the span. 055 * 056 * <p> 057 * Called by the framework only when the handler threw — immediately before {@link #close()}. 058 * Bridges typically record the throwable as a span event with the stack trace, set the span status 059 * to {@code ERROR}, and add an {@code exception.type} attribute carrying the exception's 060 * simple-name. 061 * 062 * @param error The exception thrown by the handler. Never <jk>null</jk> when this method is called. 063 */ 064 void setError(Throwable error); 065 066 /** 067 * Closes the span. 068 * 069 * <p> 070 * Always called by the framework — via the standard {@code finally}-block contract on 071 * {@link AutoCloseable} — whether the handler returned normally or threw. Implementations 072 * <b>must not</b> throw checked exceptions; the close path runs in a {@code finally} where masking 073 * the original handler exception is unsafe. Implementations that need to surface bridge-level 074 * errors should log + swallow instead. 075 */ 076 @Override 077 void close(); 078 079 /** 080 * Records a JSON-RPC-level error outcome on this span. 081 * 082 * <p> 083 * A dated MCP adapter dispatches every request over HTTP {@code 200}, so an application-level 084 * JSON-RPC error (for example an unknown tool name) never reaches {@link #setStatusCode(int)} 085 * with anything but {@code 200} and never throws into {@link #setError(Throwable)}. This method 086 * gives such a caller a neutral way to observe that outcome on the span — called from the 087 * request-scoped tracing observation before a JSON-RPC error response is returned, distinct from 088 * both the HTTP status path and the thrown-exception path. 089 * 090 * <p> 091 * Added as a source-compatible default so every existing {@link Scope} implementation keeps 092 * compiling unchanged. The default implementation is a no-op; a bridge that wants to classify 093 * JSON-RPC errors on the span (for example the OpenTelemetry bridge in 094 * {@code juneau-rest-server-tracing-otel}) overrides it. 095 * 096 * @param code The JSON-RPC error code (e.g. {@code -32601}). 097 * @param message The JSON-RPC error message. May be <jk>null</jk>. 098 */ 099 default void recordRpcError(int code, String message) { 100 // Intentionally empty; see method-level javadoc. 101 } 102}