Application Insights 和 Azure 流分析查询自定义 JSON 属性

Posted

技术标签:

【中文标题】Application Insights 和 Azure 流分析查询自定义 JSON 属性【英文标题】:Application Insights and Azure Stream Analytics Query a custom JSON property 【发布时间】:2015-07-02 19:41:13 【问题描述】:

我正在尝试使用流分析将我的 Application Insights 导出读取到 SQL 表中。

这些是我试图捕获的自定义和指标事件,因此部分 JSON 是自定义或指标事件的“名称”(例如 TestMethod1),JSON 如下所示:


  "metric": [ ],
  "internal": 
  .. host of other json data...
    "context": 
      "custom": 
      "metrics": 
      [
        
          "TestMethod1": 
          
            "value": 42.8207,
            "count": 1.0,
            "min": 42.8207,
            "max": 42.8207,
            "stdDev": 0.0
          
        
      ]
    
  

使用类似 Sql 的分析语言,我尝试使用类似于下面的语法将我的数据传输到 SQL 表(这仍然是我尝试各种方法和手段来实现这一点......)

SELECT A.internal.data.id as id
, dimensions.ArrayValue.EventName as eventName
, metrics.[value] as [value]
, A.context.data.eventTime as eventtime
, metrics.count as [count]
INTO
  MetricsOutput
FROM AppMetrics A
CROSS APPLY GetElements(A.[context].[custom].[metrics[0]]) as metrics
 CROSS APPLY GetElements(A.[context].[custom].[dimensions]) as dimensions

问题是,由于自定义事件名称,我的 [value] 和 [count] 列都没有被填充。目前,我在 metrics.value 上收到错误“具有此类名称的列不存在”。

关于如何实现这一点的任何想法?

我想为几种不同的方法输出我的指标和自定义事件,列名并不重要。但来自应用洞察导出的一个 blob 文件将包含 5 或 6 个不同自定义事件和指标的事件。

所以我可以拥有一个包含 TestMethod1、TestMethod2 和 TestMethod3 的 blob 文件,并希望将那个文件解析到表中,而不必求助于代码和工作人员角色。

问候

【问题讨论】:

***.com/questions/31528147/… 这里有一个类似的问题有答案:***.com/questions/31602577/…Ziv. 【参考方案1】:

对于将自定义维度添加为单行中的列,这对我有用:

在流分析作业的“作业拓扑 -> 函数”部分下。

首先,

添加具有以下属性的自定义函数

函数别名 - flattenCustomDimensions(可以是任何东西) 函数类型 - Javascript UDF 输出类型 - 任何

并将主函数替换为以下内容

function main(dimensions) 
  let output = ;
  for(let i in dimensions) 
    let dim = dimensions[i];
    for(let key in dim) 
      output[key] = dim[key];
    
  
  return output;

第二,

如下构成查询:

如果我们有自定义尺寸,例如

第 1 行:

"context": 
  ...
  "custom": 
    "dimensions": [
       "Dimension1": "Value1" ,
       "Dimension2": "Value2" 
    ]
  

第 2 行:

"context": 
  ...
  "custom": 
    "dimensions": [
       "Dimension1": "Value1.2" ,
       "Dimension3": "Value3" 
    ]
  

查询将是

WITH temp as (
SELECT
    *,
    UDF.flattenCustomDimensions(I.context.custom.dimensions) as dim
    FROM [Input] as I
)

SELECT
    Dim1 = temp.dim.Dimension1,
    Dim2 = temp.dim.Dimension2,
    Dim3 = temp.dim.Dimension3
INTO [Output]
FROM temp

输出表是

DIM1     |  DIM2  |  DIM3
----------------------------
Value1   | Value2 | null
Value1.2 | null   | Value3

【讨论】:

谢谢你,这太完美了! 太棒了!我只是将它重命名为 FlattenArray【参考方案2】:

您不想为您的维度使用 CROSS APPLY,因为这样它会将每个维度放在不同的行上。您想要的是将所有内容展平成一行。为此,请使用 GetRecordPropertyValue 和 GetArrayElement 函数,如下所示。

JSON 格式:


    "event": [...],
    "internal": ...,
    "context": 
        ...
        "data": 
            "isSynthetic": false,
            "eventTime": "2015-12-14T17:38:35.37Z",
            "samplingRate": 100.0
        ,
        ...
        "custom": 
            "dimensions": 
            [
                 "MyDimension1": "foo" , 
                 "MyDimension2": "bar" 
            ],
            "metrics": [
                "MyMetric1": 
                    "value": 0.39340400471142523,
                    "count": 1.0,
                    "min": 0.39340400471142523,
                    "max": 0.39340400471142523,
                    "stdDev": 0.0
                
            ]
        ,
        ...
    

查询:

SELECT
    MySource.internal.data.id AS ID,
    MySource.context.data.eventTime AS EventTime,
    GetRecordPropertyValue(GetArrayElement(MySource.context.custom.dimensions, 0), 'MyDimension1') AS MyDimension1,
    GetRecordPropertyValue(GetArrayElement(MySource.context.custom.dimensions, 1), 'MyDimension2') AS MyDimension2,
    avg(CASE WHEN MyMetrics.arrayvalue.MyMetric1.value IS NULL THEN 0 ELSE   MyMetrics.arrayvalue.MyMetric1.value END) as MetricAverage
INTO
   [output-stream]
FROM
  [input-stream] MySource
OUTER APPLY 
    GetElements(MySource.context.custom.metrics) as MyMetrics
GROUP BY 
    SlidingWindow(minute, 1), 
    MySource.internal.data.id AS ID,
    MySource.context.data.eventTime AS EventTime,
    GetRecordPropertyValue(GetArrayElement(MySource.context.custom.dimensions, 0), 'MyDimension1'),
    GetRecordPropertyValue(GetArrayElement(MySource.context.custom.dimensions, 1), 'MyDimension2')

【讨论】:

如果 MyDimension1 在维度数组中有不同的位置怎么办?如果您设置的属性因一个事件而异,那么您知道这是非常默认的场景。

以上是关于Application Insights 和 Azure 流分析查询自定义 JSON 属性的主要内容,如果未能解决你的问题,请参考以下文章

API Application Insights 使用的良好实践

使用 ServiceFabric StatefulServices 和 .Net Core 2.1 的 Application Insights

如何为 Application Insights NLog 目标设置上下文

使用Application Insights监控应用程序性能

Visual Studio 中类库的 Application Insights

使用 Application Insights 监控我的 Azure 功能