Created
December 8, 2021 18:51
-
-
Save lmolkova/95e22b5d44c88543c12f96b8158234d7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package org.example.functions; | |
| import com.azure.core.models.CloudEvent; | |
| import com.azure.core.util.serializer.TypeReference; | |
| import com.azure.messaging.eventgrid.EventGridEvent; | |
| import com.fasterxml.jackson.core.JsonProcessingException; | |
| import com.fasterxml.jackson.databind.ObjectMapper; | |
| import com.microsoft.azure.functions.ExecutionContext; | |
| import com.microsoft.azure.functions.HttpMethod; | |
| import com.microsoft.azure.functions.HttpRequestMessage; | |
| import com.microsoft.azure.functions.HttpResponseMessage; | |
| import com.microsoft.azure.functions.HttpStatus; | |
| import com.microsoft.azure.functions.annotation.AuthorizationLevel; | |
| import com.microsoft.azure.functions.annotation.EventGridTrigger; | |
| import com.microsoft.azure.functions.annotation.FunctionName; | |
| import com.microsoft.azure.functions.annotation.HttpTrigger; | |
| import io.opentelemetry.api.GlobalOpenTelemetry; | |
| import io.opentelemetry.api.trace.Span; | |
| import io.opentelemetry.api.trace.StatusCode; | |
| import io.opentelemetry.api.trace.Tracer; | |
| import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; | |
| import io.opentelemetry.context.Context; | |
| import io.opentelemetry.context.Scope; | |
| import io.opentelemetry.context.propagation.TextMapGetter; | |
| import io.opentelemetry.context.propagation.TextMapPropagator; | |
| import java.util.HashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.Optional; | |
| import java.util.logging.Logger; | |
| public class HttpTriggerFunction { | |
| // make sure to enable Application Insights (preview) support for Azure Functions: | |
| // https://docs.microsoft.com/azure/azure-monitor/app/monitor-functions | |
| private final static Tracer TRACER = GlobalOpenTelemetry.getTracer("my-function"); | |
| private static final TextMapPropagator PROPAGATOR = W3CTraceContextPropagator.getInstance(); | |
| // Helper class that reads trace context from CloudEvent | |
| private static final TextMapGetter<Map<String, Object>> GETTER = new TextMapGetter<Map<String, Object>>() { | |
| @Override | |
| public Iterable<String> keys(Map<String, Object> carrier) { | |
| return carrier.keySet(); | |
| } | |
| @Override | |
| public String get(Map<String, Object> carrier, String key) { | |
| return carrier.get(key).toString(); | |
| } | |
| }; | |
| @FunctionName("HttpExample") | |
| public HttpResponseMessage run( | |
| @HttpTrigger( | |
| name = "req", | |
| methods = {HttpMethod.GET, HttpMethod.POST, HttpMethod.OPTIONS}, | |
| authLevel = AuthorizationLevel.ANONYMOUS) | |
| HttpRequestMessage<Optional<String>> request, | |
| final ExecutionContext context) { | |
| context.getLogger().info("Java HTTP trigger processed a request."); | |
| if (request.getHttpMethod() == HttpMethod.OPTIONS) { | |
| String header = request.getHeaders().get("WebHook-Request-Origin"); | |
| return request.createResponseBuilder(HttpStatus.OK).header("Webhook-Allowed-Origin", header).build(); | |
| } | |
| if (request.getBody().isPresent()) { | |
| List<CloudEvent> events = CloudEvent.fromString(request.getBody().get()); | |
| events.stream().forEach( event -> { | |
| Context traceContext = W3CTraceContextPropagator.getInstance().extract(Context.current(), event.getExtensionAttributes(), GETTER); | |
| processWithTracing(event, traceContext, context.getLogger()); | |
| }); | |
| } | |
| return request.createResponseBuilder(HttpStatus.OK).body("Hello").build(); | |
| } | |
| @FunctionName("CloudEvent") | |
| public void logEvent1(@EventGridTrigger(name = "cloudEvent") String eventsStr, final ExecutionContext context) { | |
| List<CloudEvent> events = CloudEvent.fromString(eventsStr); | |
| events.stream().forEach( event -> { | |
| Context traceContext = W3CTraceContextPropagator.getInstance().extract(Context.current(), event.getExtensionAttributes(), GETTER); | |
| processWithTracing(event, traceContext, context.getLogger()); | |
| }); | |
| } | |
| @FunctionName("EventGridEvent") | |
| public void logEvent2(@EventGridTrigger(name = "eventGridEvent") String eventsStr, final ExecutionContext context) { | |
| List<EventGridEvent> events = EventGridEvent.fromString(eventsStr); | |
| events.stream().forEach( event -> { | |
| // For optimal performance, change data type to your model representing EventGridEvent payload. | |
| // Make sure to add `traceparent` and `tracestate` properties to your model. | |
| Map<String, Object> dataObj = event.getData().toObject(new TypeReference<Map<String, Object>>() { }); | |
| Context traceContext = W3CTraceContextPropagator.getInstance().extract(Context.current(), dataObj, GETTER); | |
| processWithTracing(event, traceContext, context.getLogger()); | |
| }); | |
| } | |
| private void processWithTracing(Object myEventData, Context traceContext, Logger logger) { | |
| // Start a new span: it is nested under function execution | |
| // and linked to context from the event. | |
| Span span = TRACER.spanBuilder("Process event") | |
| .addLink(Span.fromContext(traceContext).getSpanContext()) | |
| .startSpan(); | |
| try (Scope unused = span.makeCurrent()) { | |
| // process the event here | |
| logger.info("Processing event... " + myEventData); | |
| } catch (Exception ex) { | |
| span.setStatus(StatusCode.ERROR); | |
| span.end(); | |
| } finally { | |
| span.end(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment