forked from Azure-Samples/openai-python-enterprise-logging
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapim-policy-event-hub-logging.xml
146 lines (132 loc) · 6.95 KB
/
apim-policy-event-hub-logging.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!--
This sample policy enforces Azure AD authentication and authorization to the Azure OpenAI Service.
It limits the authorization tokens issued by the organization's tenant for Cognitive Services.
The authorization token is passed on to the Azure OpenAI Service ensuring authorization to the actions within
the service are limited to the permissions defined in Azure RBAC.
The sample policy also logs audit information such as the application id making the call, the prompt, the response,
the model used, and the number of tokens consumed. This can be helpful when handling chargebacks. The events are delivered
to an Azure Event Hub through the Azure API Management Logger.
You must provide values for the AZURE_OAI_SERVICE_NAME, TENANT_ID, YOUR_LOGGER variables.
You can use separate APIM Loggers for compliance and chargeback or the same logger. It is your choice.
Authored by Matthew Felton 6/2023 - https://www.linkedin.com/in/matthewfeltonma/
-->
<policies>
<inbound>
<base />
<validate-jwt header-name="Authorization" failed-validation-httpcode="403" failed-validation-error-message="Forbidden">
<openid-config url="https://login.microsoftonline.com/{{TENANT_ID}}/v2.0/.well-known/openid-configuration" />
<issuers>
<issuer>https://sts.windows.net/{{TENANT_ID}}/</issuer>
</issuers>
<required-claims>
<claim name="aud">
<value>https://cognitiveservices.azure.com</value>
</claim>
</required-claims>
</validate-jwt>
<set-variable name="message-id" value="@(Guid.NewGuid())" />
<log-to-eventhub logger-id="{{YOUR_LOGGER}}" partition-id="0">@{
var requestBody = context.Request.Body?.As<JObject>(true);
string prompt = string.Empty;
string messages = string.Empty;
string model = string.Empty;
if(requestBody != null)
{
prompt = requestBody["prompt"]?.ToString();
messages = requestBody["messages"]?.ToString();
model = requestBody["model"]?.ToString();
}
string operation = context.Operation.Id;
string result = string.Empty;
switch(operation)
{
case "get-a-generated-image-result":
result = new JObject(
new JProperty("event-type", "Request"),
new JProperty("event-time", DateTime.UtcNow.ToString()),
new JProperty("backend", context.Request.Url.Host.ToString()),
new JProperty("message-id", context.Variables["message-id"]),
new JProperty("operation", operation)
).ToString();
break;
default:
result = new JObject(
new JProperty("event-type", "Request"),
new JProperty("event-time", DateTime.UtcNow.ToString()),
new JProperty("backend", context.Request.Url.Host.ToString()),
new JProperty("message-id", context.Variables["message-id"]),
new JProperty("operation", operation),
new JProperty("model", model),
new JProperty("prompt", prompt),
new JProperty("messages", messages)
).ToString();
break;
}
return result;
}</log-to-eventhub>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<log-to-eventhub logger-id="{{YOUR_LOGGER}}" partition-id="0">@{
var responseBody = context.Response.Body?.As<JObject>(true);
var operation = context.Operation.Id;
string response = responseBody["choices"]?.ToString();
string result = string.Empty;
switch(operation)
{
case "ChatCompletions_Create":
case "Completions_Create":
result = new JObject(
new JProperty("event-type", "Response"),
new JProperty("event-time", DateTime.UtcNow.ToString()),
new JProperty("backend", context.Request.Url.Host.ToString()),
new JProperty("message-id", context.Variables["message-id"]),
new JProperty("choices",response),
new JProperty("operation", operation),
new JProperty("apiId", context.Api.Id),
new JProperty("productId", context.Product.Id),
new JProperty("model", responseBody["model"].ToString()),
new JProperty("modeltime", context.Response.Headers.GetValueOrDefault("Openai-Processing-Ms",string.Empty)),
new JProperty("completion_tokens", responseBody["usage"]["completion_tokens"].ToString()),
new JProperty("prompt_tokens", responseBody["usage"]["prompt_tokens"].ToString()),
new JProperty("total_tokens", responseBody["usage"]["total_tokens"].ToString())
).ToString();
break;
case "embeddings_create":
result = new JObject(
new JProperty("event-type", "Response"),
new JProperty("event-time", DateTime.UtcNow.ToString()),
new JProperty("backend", context.Request.Url.Host.ToString()),
new JProperty("message-id", context.Variables["message-id"]),
new JProperty("operation", operation),
new JProperty("apiId", context.Api.Id),
new JProperty("productId", context.Product.Id),
new JProperty("model", responseBody["model"].ToString()),
new JProperty("modeltime", context.Response.Headers.GetValueOrDefault("Openai-Processing-Ms",string.Empty)),
new JProperty("prompt_tokens", responseBody["usage"]["prompt_tokens"].ToString()),
new JProperty("total_tokens", responseBody["usage"]["total_tokens"].ToString())
).ToString();
break;
default:
result = new JObject(
new JProperty("event-type", "Response"),
new JProperty("event-time", DateTime.UtcNow.ToString()),
new JProperty("backend", context.Request.Url.Host.ToString()),
new JProperty("message-id", context.Variables["message-id"]),
new JProperty("operation", operation),
new JProperty("apiId", context.Api.Id),
new JProperty("productId", context.Product.Id),
new JProperty("modeltime", context.Response.Headers.GetValueOrDefault("Openai-Processing-Ms",string.Empty))
).ToString();
break;
}
return result;
}</log-to-eventhub>
</outbound>
<on-error>
<base />
</on-error>
</policies>