Application Insights和Azure Stream Analytics查询自定义JSON属性

时间:2015-07-02 19:41:14

标签: azure-stream-analytics azure-application-insights

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

这些是我尝试捕获的自定义和公制事件,因此部分JSON是" name"自定义或度量事件(例如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文件,并希望将这一个文件解析到表中,而不必诉诸代码和辅助角色。

此致

2 个答案:

答案 0 :(得分:3)

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

在Stream Analytics作业的 “作业拓扑 - >功能” 部分下。

首先,

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

  • 功能别名 - flattenCustomDimensions (可以是任何内容)
  • 功能类型 - Javascript UDF
  • 输出类型 - 任何

用以下

替换main函数
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;
}

Add custom function

<强>其次,

按如下方式构建查询:

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

ROW1:

"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

答案 1 :(得分:1)

你没有&#39;想要对您的尺寸使用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')