2. Go中defer使用注意事项
463 2023-04-03 03:59:54
根据文档 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 策略。
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/
两种方式任选其一:
{ "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" } }}
{ "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 }}
inbound
或 outbound
策略部分中。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>
下载zip包,解压后在里面找到文件名为:ServiceBusExplorer.exe。 双击即可运行
在下面的字符串框中输入Event Hub Namespace的连接字符串。点击Save/ OK后,即可连接到Event Hub中。
进入保存日志的Event Hub中,找到合适的分区数,点击“Create Partitions Listener ”, 然后再弹出的页面中点击 “Strat”按钮,就可以收到Event Hub中所存储的消息
使用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