1
votes

I'm trying to log the requests and responses from API Management Gateway to Azure Event Hubs.I'm using "log-to-event-hub" policy for that.I want to send a single event to event hub containing both the request and response together.

I tried including the event-hub policy inside the inbound policy with both the request and response together but I'm only getting the request and not the response.Similarly I tried including it in the outbound policy but got only the response.As I'm sending the event-hub logs to Azure Log Analytics I wanted to get the complete request and response together.I know that keeping the "log-to-event-hub" policy in both inbound and outbound policies will give me two different log events.

<inbound>
    <set-variable name="message-id" value="@(Guid.NewGuid())" />
    <log-to-eventhub logger-id="all-logs" partition-id="0">@{
      var requestLine = string.Format("{0} {1} HTTP/1.1\r\n",
                                                  context.Request.Method,
                                                  context.Request.Url.Path + context.Request.Url.QueryString);

      var body = "Request " + context.Request.Body?.As<string>(true) + "Response " + context.Response.Body?.As<string>(true);
      var headers = context.Request.Headers
                           .Where(h => h.Key != "Authorization" && h.Key != "Ocp-Apim-Subscription-Key")
                           .Select(h => string.Format("{0}: {1}", h.Key, String.Join(", ", h.Value)))
                           .ToArray<string>();

      var headerString = (headers.Any()) ? string.Join("\r\n", headers) + "\r\n" : string.Empty;

      return "staging: " +   context.Response.StatusCode  + " " + context.Variables["message-id"] + "\n"
                          + requestLine + headerString + "\r\n" + body;
  }</log-to-eventhub>
</inbound>

Is it possible to have both in the same event and only one event is being logged.

1

1 Answers

6
votes

I would capture the required values from request in a variable, combine it with request values in the outbound policy and log it there:

<policies>
    <inbound>
        <base />
        <set-variable name="requestHeaders" value="@(JsonConvert.SerializeObject(context.Request.Headers))" />
        <set-variable name="requestBody" value="@(context.Request.Body.As<string>(true))" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <log-to-eventhub logger-id="testlogger">@{
            var content = new JObject();
            content["reqHeaders"] = context.Variables.GetValueOrDefault<string>("requestHeaders");
            content["reqBody"] = context.Variables.GetValueOrDefault<string>("requestBody");
            content["resStatus"] = JsonConvert.SerializeObject(context.Response.StatusCode);
            content["resBody"] = context.Response.Body.As<string>(true);
            return content.ToString();
        }</log-to-eventhub>
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>