zoukankan      html  css  js  c++  java
  • 【Azure API 管理】在APIM 中添加 logtoeventhub 策略,把 Request Body 信息全部记录在Event Hub中

    问题描述

    根据文档 https://docs.azure.cn/zh-cn/api-management/api-management-howto-log-event-hubs , 可以将Azure API Management中的请求记录到Azure 事件中心。文档中有详细的步骤描述。但是在对于如何创建APIM的Logger, 如何在API中配置策略描述非常不清楚,所以本文就补充如何创建Logger及在APIM的API中添加log-to-eventhub 策略。

    前提条件

    • Postman

     

    操作步骤

    1) 创建APIM Logger 

    示例

     PUT https://management.chinacloudapi.cn/subscriptions/<your subscription id>/resourceGroups/<group name>/providers/Microsoft.ApiManagement/service/<your apim name>/loggers/<loggerideh01>?api-version=2020-12-01

    注:替换<>中的内容为自己的相应资源信息,同时也定义loggers的名称。

           这里的Endpoint为中国区Azure的Endpoint: https://management.chinacloudapi.cn/, 如果需要Global Azure,则为:https://management.azure.com/

    Authorization

    两种方式任选其一:

    1. Azure Active Directory OAuth2 Flow :  https://www.cnblogs.com/lulight/p/14279338.html
    2. 似乎用浏览器打开Azure APIM的门户,通过F12--开发者选项中的 Network, 查看其中对API的请求,复制其中的Authorization 值

    Body

    {
      "properties": {
        "loggerType": "azureEventHub",
        "description": "adding a new logger",
        "credentials": {
          "name": "<your event hub name>",
          "connectionString": "Endpoint=sb://<your event hub namespace>.servicebus.chinacloudapi.cn/;SharedAccessKeyName=xxxxxxxxxxxxxxxxx;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
      }
    }

    Response - 201 Created 

    {
        "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxx-rg/providers/Microsoft.ApiManagement/service/xxxx/loggers/loggerideh01",
        "type": "Microsoft.ApiManagement/service/loggers",
        "name": "loggerideh01",
        "properties": {
            "loggerType": "azureEventHub",
            "description": "adding a new logger",
            "credentials": {
                "name": "xxxxxxxxxxxx",
                "connectionString": "{{Logger-Credentials--xxxxxxxxxxxx}}"
            },
            "isBuffered": true,
            "resourceId": null
        }
    }

    演示动画

     

    2) 添加 log-to-eventhub 策略

    1. 浏览到自己的 APIM 实例。
    2. 选择“API”选项卡。
    3. 选择要将策略添加到的 API。
    4. 选择“所有操作”。
    5. 选择屏幕顶部的“设计”选项卡。
    6. 在“入站或出站处理”窗口中,单击三角形(铅笔旁边)。
    7. 选择“代码编辑器”。 有关详细信息,请参阅如何设置或编辑策略
    8. 将光标放在 inbound 或 outbound 策略部分中。
    9. 在右侧窗口中,选择“高级策略” > “记录到 EventHub”。 这会插入 log-to-eventhub 策略语句模板。

    注: Log-to-eventhub 中的logger-id由上面第一步创建。 Request Body的信息一定要进行格式转换。所以需要使用   context.Request.Body.As<string>() 

    <policies>
        <inbound>
            <base />
            <log-to-eventhub logger-id="loggerideh01">@{
            return new JObject(
                new JProperty("EventTime", DateTime.UtcNow.ToString()),
                new JProperty("ServiceName", context.Deployment.ServiceName),
                new JProperty("RequestId", context.RequestId),
                new JProperty("RequestBody1", context.Request.Body.As<string>()),
                new JProperty("OperationName", context.Operation.Name)
            ).ToString();
        }</log-to-eventhub>
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <base />
            <log-to-eventhub logger-id="loggerideh01">@{
            return new JObject(
                new JProperty("EventTime", DateTime.UtcNow.ToString()),
                new JProperty("ServiceName", context.Deployment.ServiceName),
                new JProperty("RequestId", context.RequestId),
                new JProperty("RequestBody2", context.Response.Body.As<string>()),
                new JProperty("OperationName", context.Operation.Name)
            ).ToString();
        }</log-to-eventhub>
        </outbound>
        <on-error>
            <base />
        </on-error>
    </policies>

    3) 连接到Event Hub,查看 Request Body 信息

    下载zip包,解压后在里面找到文件名为:ServiceBusExplorer.exe。 双击即可运行

    在下面的字符串框中输入Event Hub Namespace的连接字符串。点击Save/ OK后,即可连接到Event Hub中。

    进入保存日志的Event Hub中,找到合适的分区数,点击“Create Partitions Listener ”, 然后再弹出的页面中点击 “Strat”按钮,就可以收到Event Hub中所存储的消息

    附录一:如何在APIM的Policy set-variable 中为参数在进行格式转换时候进行验证是否为null呢?避免Expression evaluation failed. 

    使用C#的问号表达式 (condition == null ? value1 :value2)

    在APIM中,如果在测试阶段,出现Expression evaluation failed错误,可以在Test 的Trace中进行查看,了解真实的错误信息。如:

    {
                    "source": "log-to-eventhub",
                    "timestamp": "2021-12-01T03:25:33.7362765Z",
                    "elapsed": "00:00:00.0007502",
                    "data": {
                        "messages": [
                            {
                                "message": "Expression evaluation failed.",
                                "expression": "\n        return new JObject(\n            new JProperty(\"EventTime\", DateTime.UtcNow.ToString()),\n            new JProperty(\"ServiceName\", context.Deployment.ServiceName),\n            new JProperty(\"RequestId\", context.RequestId),\n            new JProperty(\"RequestIp\", context.Request.Body),\n            new JProperty(\"OperationName\", context.Operation.Name)\n        ).ToString();\n    ",
                                "details": "Could not determine JSON object type for type Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.MessageBody.\r\n   at Newtonsoft.Json.Linq.JValue.GetValueType(Nullable`1 current, Object value)\r\n   at Newtonsoft.Json.Linq.JContainer.CreateFromContent(Object content)\r\n   at Newtonsoft.Json.Linq.JProperty..ctor(String name, Object content)"
                            },
                            "Expression evaluation failed. Could not determine JSON object type for type Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.MessageBody.\r\n   at Newtonsoft.Json.Linq.JValue.GetValueType(Nullable`1 current, Object value)\r\n   at Newtonsoft.Json.Linq.JContainer.CreateFromContent(Object content)\r\n   at Newtonsoft.Json.Linq.JProperty..ctor(String name, Object content)",
                            "Could not determine JSON object type for type Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.MessageBody."
                        ]
                    }
                }

    为了避免这样的情况,在格式转换时候,最好对其进行 null 检测,当时 null的时候就可以改变其值的或者赋值为“”。

      <set-variable name="testvalue" value="@(context.Variables["tokenvalue"]==null?context.Request.Headers.GetValueOrDefault("User-Agent","empty"):"")" />

      <set-variable name="requestbody" value="@(context.Request.Body==null?"no body":context.Request.Body.As<string>())" />

    参考资料

    如何在 Azure API 管理中将事件记录到 Azure 事件中心 : https://docs.azure.cn/zh-cn/api-management/api-management-howto-log-event-hubs#configure-log-to-eventhub-policies

    Logger - Create Or Update : https://docs.microsoft.com/zh-cn/rest/api/apimanagement/2020-12-01/logger/create-or-update#apimanagementcreateehlogger

    创建 Azure 事件中心:https://docs.azure.cn/zh-cn/event-hubs/event-hubs-create 

    下载 Service Bus Explorer查看事件中心消息:https://github.com/paolosalvatori/ServiceBusExplorer/releases

     

    当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

  • 相关阅读:
    《当程序员的那些狗日日子》(二十七)大项目
    《当程序员的那些狗日日子》(四十二)内心的挣扎
    《当程序员的那些狗日日子》(二十一)加班,加班
    《当程序员的那些狗日日子》(三十四)人事变动
    《当程序员的那些狗日日子》(五十二)同学情与差距
    《当程序员的那些狗日日子》(四十四)是办公室还是牢房
    《当程序员的那些狗日日子》(四十七)躁动的空气
    《当程序员的那些狗日日子》(三十七)黯然离去
    《当程序员的那些狗日日子》(十六)告别
    《当程序员的那些狗日日子》(二十三)死在了今天的晚上
  • 原文地址:https://www.cnblogs.com/lulight/p/15630965.html
Copyright © 2011-2022 走看看