I got this to work using the following component. Any number of headers can be added as metrics tags by modifying the list getHeadersToTag
statically
import static org.springframework.util.StringUtils.hasText;
import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.server.observation.ServerRequestObservationContext;
import org.springframework.stereotype.Component;
/*
* This component is responsible for extracting the headers(by default VCC-Client-Id) from incoming HTTP
* request and appending it as tag to all the controller metrics.
*/
@Component
public class HeaderAsMetricTagAppender extends DefaultServerRequestObservationConvention {
private static List<String> headersToTag;
public static final String DEFAULT_VCC_CLIENT_ID = "default";
static {
headersToTag = new ArrayList<>();
headersToTag.add(DEFAULT_VCC_CLIENT_ID);
}
@Override
public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) {
return super.getLowCardinalityKeyValues(context).and(additionalTags(context));
}
protected static KeyValues additionalTags(ServerRequestObservationContext context) {
KeyValues keyValues = KeyValues.empty();
for (String headerName : headersToTag) {
String headerValue = "undefined";
HttpServletRequest servletRequest = context.getCarrier();
if (servletRequest != null && hasText(servletRequest.getHeader(headerName))) {
headerValue = servletRequest.getHeader(headerName);
}
// header tag will be added in all the controller metrics
keyValues = keyValues.and(KeyValue.of(headerName, headerValue));
}
return keyValues;
}
/**
* The list of headers to be added as tags can be modified using this list.
*
* @return reference to the list of all the headers to be added as tags
*/
public static List<String> getHeadersToTag() {
return headersToTag;
}
}
Don't add headers that can have large set value possibilities. This would the increase the metric cardinality\
Thanks to Bunty Raghani https://github.com/BootcampToProd/spring-boot-3-extended-server-request-observation-convention/tree/main