All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nike.wingtips.servlet.HttpSpanFactory Maven / Gradle / Ivy

package com.nike.wingtips.servlet;

import com.nike.wingtips.Span;
import com.nike.wingtips.Span.SpanPurpose;
import com.nike.wingtips.http.HttpRequestTracingUtils;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

/**
 * Creates {@link Span} objects extracted from a {@link HttpServletRequest}. NOTE: If a span exists in the request but is not explicitly defined with
 * {@link com.nike.wingtips.TraceHeaders#TRACE_SAMPLED} set to false, then {@link #fromHttpServletRequest(HttpServletRequest, List)} will default it to be sampleable.
 */
public class HttpSpanFactory {

    /**
     * Intentionally private to force all access through static methods.
     */
    private HttpSpanFactory() {
        // Nothing to do
    }

    /**
     * @param servletRequest The incoming request that may have {@link Span} information embedded in the headers. If this argument is null then this method will return null.
     * @param userIdHeaderKeys This list of header keys will be used to search the request headers for a user ID to set on the returned span. The user ID header keys
     *                         will be searched in list order, and the first non-empty user ID header value found will be used as the {@link Span#getUserId()}.
     *                         You can safely pass in null or an empty list for this argument if there is no user ID to extract; if you pass in null then the returned
     *                         span's {@link Span#getUserId()} will be null.
     *
     * @return The {@link Span} stored in the given request's trace headers (e.g. {@link com.nike.wingtips.TraceHeaders#TRACE_ID}, {@link com.nike.wingtips.TraceHeaders#TRACE_SAMPLED},
     *         {@link com.nike.wingtips.TraceHeaders#PARENT_SPAN_ID}, etc), or null if the request is null or doesn't contain the necessary headers.
     *         
* NOTE: {@link com.nike.wingtips.TraceHeaders#TRACE_ID} is the minimum header needed to return a non-null {@link Span}. If {@link com.nike.wingtips.TraceHeaders#SPAN_ID} * is missing then a new span ID will be generated using {@link com.nike.wingtips.TraceAndSpanIdGenerator#generateId()}. * If {@link com.nike.wingtips.TraceHeaders#TRACE_SAMPLED} is missing then the returned span will be sampleable. If {@link com.nike.wingtips.TraceHeaders#SPAN_NAME} * is missing then {@link HttpRequestTracingUtils#UNSPECIFIED_SPAN_NAME} will be used as the span name. */ public static Span fromHttpServletRequest(HttpServletRequest servletRequest, List userIdHeaderKeys) { if (servletRequest == null) return null; return HttpRequestTracingUtils.fromRequestWithHeaders(new RequestWithHeadersServletAdapter(servletRequest), userIdHeaderKeys); } /** * @return A {@link Span} object created from the headers if they exist (see {@link #fromHttpServletRequest(HttpServletRequest, List)} for details), or if the headers don't * have enough information then this will return a new root span with a span name based on the results of {@link #getSpanName(HttpServletRequest)} and user ID based * on the result of {@link #getUserIdFromHttpServletRequest(HttpServletRequest, List)}. Since this method is for a server receiving a request * the returned span's {@link Span#getSpanPurpose()} will be {@link SpanPurpose#SERVER}. */ public static Span fromHttpServletRequestOrCreateRootSpan(HttpServletRequest servletRequest, List userIdHeaderKeys) { Span span = fromHttpServletRequest(servletRequest, userIdHeaderKeys); if (span == null) { span = Span .generateRootSpanForNewTrace(getSpanName(servletRequest), SpanPurpose.SERVER) .withUserId(getUserIdFromHttpServletRequest(servletRequest, userIdHeaderKeys)) .build(); } return span; } /** * Attempts to pull a valid ID for the user making the request. * * @return The HTTP Header value of the user ID if it exists, null otherwise. The request's headers will be inspected for the user ID using the given list of userIdHeaderKeys * in list order - the first one found that is not null/empty will be returned. */ public static String getUserIdFromHttpServletRequest(HttpServletRequest servletRequest, List userIdHeaderKeys) { if (servletRequest == null) return null; return HttpRequestTracingUtils.getUserIdFromRequestWithHeaders(new RequestWithHeadersServletAdapter(servletRequest), userIdHeaderKeys); } /** * @return Span name appropriate for a new root span for this request */ public static String getSpanName(HttpServletRequest request) { // Try the servlet path first, and fall back to the raw request URI. String path = request.getServletPath(); if (path == null || path.trim().length() == 0) path = request.getRequestURI(); // Include the HTTP method in the returned value to help delineate which endpoint this request represents. return request.getMethod() + '_' + path; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy