Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
9164a352
Unverified
Commit
9164a352
authored
Jul 07, 2020
by
Kyle Brandt
Committed by
GitHub
Jul 07, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Azure: Restore Insights Metrics alias feature (#26098)
also fix case sensitivity for azure monitor metrics
parent
eb4391a2
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
124 additions
and
11 deletions
+124
-11
pkg/tsdb/azuremonitor/applicationinsights-datasource.go
+63
-0
pkg/tsdb/azuremonitor/applicationinsights-metrics_test.go
+47
-0
pkg/tsdb/azuremonitor/azuremonitor-datasource.go
+13
-10
pkg/tsdb/azuremonitor/azuremonitor-datasource_test.go
+1
-1
No files found.
pkg/tsdb/azuremonitor/applicationinsights-datasource.go
View file @
9164a352
...
@@ -9,6 +9,7 @@ import (
...
@@ -9,6 +9,7 @@ import (
"net/http"
"net/http"
"net/url"
"net/url"
"path"
"path"
"sort"
"strings"
"strings"
"time"
"time"
...
@@ -192,6 +193,9 @@ func (e *ApplicationInsightsDatasource) executeQuery(ctx context.Context, query
...
@@ -192,6 +193,9 @@ func (e *ApplicationInsightsDatasource) executeQuery(ctx context.Context, query
queryResult
.
Error
=
err
queryResult
.
Error
=
err
return
queryResult
,
nil
return
queryResult
,
nil
}
}
applyInsightsMetricAlias
(
frame
,
query
.
Alias
)
queryResult
.
Dataframes
=
tsdb
.
NewDecodedDataFrames
(
data
.
Frames
{
frame
})
queryResult
.
Dataframes
=
tsdb
.
NewDecodedDataFrames
(
data
.
Frames
{
frame
})
return
queryResult
,
nil
return
queryResult
,
nil
}
}
...
@@ -249,3 +253,62 @@ func (e *ApplicationInsightsDatasource) getPluginRoute(plugin *plugins.DataSourc
...
@@ -249,3 +253,62 @@ func (e *ApplicationInsightsDatasource) getPluginRoute(plugin *plugins.DataSourc
return
pluginRoute
,
pluginRouteName
,
nil
return
pluginRoute
,
pluginRouteName
,
nil
}
}
// formatApplicationInsightsLegendKey builds the legend key or timeseries name
// Alias patterns like {{metric}} are replaced with the appropriate data values.
func
formatApplicationInsightsLegendKey
(
alias
string
,
metricName
string
,
labels
data
.
Labels
)
string
{
// Could be a collision problem if there were two keys that varied only in case, but I don't think that would happen in azure.
lowerLabels
:=
data
.
Labels
{}
for
k
,
v
:=
range
labels
{
lowerLabels
[
strings
.
ToLower
(
k
)]
=
v
}
keys
:=
make
([]
string
,
0
,
len
(
labels
))
for
k
:=
range
lowerLabels
{
keys
=
append
(
keys
,
k
)
}
keys
=
sort
.
StringSlice
(
keys
)
result
:=
legendKeyFormat
.
ReplaceAllFunc
([]
byte
(
alias
),
func
(
in
[]
byte
)
[]
byte
{
metaPartName
:=
strings
.
Replace
(
string
(
in
),
"{{"
,
""
,
1
)
metaPartName
=
strings
.
Replace
(
metaPartName
,
"}}"
,
""
,
1
)
metaPartName
=
strings
.
ToLower
(
strings
.
TrimSpace
(
metaPartName
))
switch
metaPartName
{
case
"metric"
:
return
[]
byte
(
metricName
)
case
"dimensionname"
,
"groupbyname"
:
return
[]
byte
(
keys
[
0
])
case
"dimensionvalue"
,
"groupbyvalue"
:
return
[]
byte
(
lowerLabels
[
keys
[
0
]])
}
if
v
,
ok
:=
lowerLabels
[
metaPartName
];
ok
{
return
[]
byte
(
v
)
}
return
in
})
return
string
(
result
)
}
func
applyInsightsMetricAlias
(
frame
*
data
.
Frame
,
alias
string
)
{
if
alias
==
""
{
return
}
for
_
,
field
:=
range
frame
.
Fields
{
if
field
.
Type
()
==
data
.
FieldTypeTime
||
field
.
Type
()
==
data
.
FieldTypeNullableTime
{
continue
}
displayName
:=
formatApplicationInsightsLegendKey
(
alias
,
field
.
Name
,
field
.
Labels
)
if
field
.
Config
==
nil
{
field
.
Config
=
&
data
.
FieldConfig
{}
}
field
.
Config
.
DisplayName
=
displayName
}
}
pkg/tsdb/azuremonitor/applicationinsights-metrics_test.go
View file @
9164a352
...
@@ -18,6 +18,7 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
...
@@ -18,6 +18,7 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
name
string
name
string
testFile
string
testFile
string
metric
string
metric
string
alias
string
agg
string
agg
string
dimensions
[]
string
dimensions
[]
string
expectedFrame
func
()
*
data
.
Frame
expectedFrame
func
()
*
data
.
Frame
...
@@ -102,6 +103,49 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
...
@@ -102,6 +103,49 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
return
frame
return
frame
},
},
},
},
{
name
:
"segmented series with alias"
,
testFile
:
"applicationinsights/4-application-insights-response-metrics-multi-segmented.json"
,
metric
:
"traces/count"
,
alias
:
"{{ metric }}: Country,City: {{ client/countryOrRegion }},{{ client/city }}"
,
agg
:
"sum"
,
dimensions
:
[]
string
{
"client/countryOrRegion"
,
"client/city"
},
expectedFrame
:
func
()
*
data
.
Frame
{
frame
:=
data
.
NewFrame
(
""
,
data
.
NewField
(
"StartTime"
,
nil
,
[]
time
.
Time
{
time
.
Date
(
2020
,
6
,
25
,
16
,
15
,
32
,
14e7
,
time
.
UTC
),
time
.
Date
(
2020
,
6
,
25
,
16
,
16
,
0
,
0
,
time
.
UTC
),
}),
data
.
NewField
(
"traces/count"
,
data
.
Labels
{
"client/city"
:
"Washington"
,
"client/countryOrRegion"
:
"United States"
},
[]
*
float64
{
pointer
.
Float64
(
2
),
nil
,
})
.
SetConfig
(
&
data
.
FieldConfig
{
DisplayName
:
"traces/count: Country,City: United States,Washington"
}),
data
.
NewField
(
"traces/count"
,
data
.
Labels
{
"client/city"
:
"Des Moines"
,
"client/countryOrRegion"
:
"United States"
},
[]
*
float64
{
pointer
.
Float64
(
2
),
pointer
.
Float64
(
1
),
})
.
SetConfig
(
&
data
.
FieldConfig
{
DisplayName
:
"traces/count: Country,City: United States,Des Moines"
}),
data
.
NewField
(
"traces/count"
,
data
.
Labels
{
"client/city"
:
""
,
"client/countryOrRegion"
:
"United States"
},
[]
*
float64
{
nil
,
pointer
.
Float64
(
11
),
})
.
SetConfig
(
&
data
.
FieldConfig
{
DisplayName
:
"traces/count: Country,City: United States,"
}),
data
.
NewField
(
"traces/count"
,
data
.
Labels
{
"client/city"
:
"Chicago"
,
"client/countryOrRegion"
:
"United States"
},
[]
*
float64
{
nil
,
pointer
.
Float64
(
3
),
})
.
SetConfig
(
&
data
.
FieldConfig
{
DisplayName
:
"traces/count: Country,City: United States,Chicago"
}),
data
.
NewField
(
"traces/count"
,
data
.
Labels
{
"client/city"
:
"Tokyo"
,
"client/countryOrRegion"
:
"Japan"
},
[]
*
float64
{
nil
,
pointer
.
Float64
(
1
),
})
.
SetConfig
(
&
data
.
FieldConfig
{
DisplayName
:
"traces/count: Country,City: Japan,Tokyo"
}),
)
return
frame
},
},
}
}
for
_
,
tt
:=
range
tests
{
for
_
,
tt
:=
range
tests
{
t
.
Run
(
tt
.
name
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
tt
.
name
,
func
(
t
*
testing
.
T
)
{
...
@@ -110,6 +154,9 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
...
@@ -110,6 +154,9 @@ func TestInsightsMetricsResultToFrame(t *testing.T) {
frame
,
err
:=
InsightsMetricsResultToFrame
(
res
,
tt
.
metric
,
tt
.
agg
,
tt
.
dimensions
)
frame
,
err
:=
InsightsMetricsResultToFrame
(
res
,
tt
.
metric
,
tt
.
agg
,
tt
.
dimensions
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
applyInsightsMetricAlias
(
frame
,
tt
.
alias
)
if
diff
:=
cmp
.
Diff
(
tt
.
expectedFrame
(),
frame
,
data
.
FrameTestCompareOptions
()
...
);
diff
!=
""
{
if
diff
:=
cmp
.
Diff
(
tt
.
expectedFrame
(),
frame
,
data
.
FrameTestCompareOptions
()
...
);
diff
!=
""
{
t
.
Errorf
(
"Result mismatch (-want +got):
\n
%s"
,
diff
)
t
.
Errorf
(
"Result mismatch (-want +got):
\n
%s"
,
diff
)
}
}
...
...
pkg/tsdb/azuremonitor/azuremonitor-datasource.go
View file @
9164a352
...
@@ -338,6 +338,17 @@ func formatAzureMonitorLegendKey(alias string, resourceName string, metricName s
...
@@ -338,6 +338,17 @@ func formatAzureMonitorLegendKey(alias string, resourceName string, metricName s
endIndex
:=
strings
.
Index
(
seriesID
,
"/providers"
)
endIndex
:=
strings
.
Index
(
seriesID
,
"/providers"
)
resourceGroup
:=
seriesID
[
startIndex
:
endIndex
]
resourceGroup
:=
seriesID
[
startIndex
:
endIndex
]
// Could be a collision problem if there were two keys that varied only in case, but I don't think that would happen in azure.
lowerLabels
:=
data
.
Labels
{}
for
k
,
v
:=
range
labels
{
lowerLabels
[
strings
.
ToLower
(
k
)]
=
v
}
keys
:=
make
([]
string
,
0
,
len
(
labels
))
for
k
:=
range
lowerLabels
{
keys
=
append
(
keys
,
k
)
}
keys
=
sort
.
StringSlice
(
keys
)
result
:=
legendKeyFormat
.
ReplaceAllFunc
([]
byte
(
alias
),
func
(
in
[]
byte
)
[]
byte
{
result
:=
legendKeyFormat
.
ReplaceAllFunc
([]
byte
(
alias
),
func
(
in
[]
byte
)
[]
byte
{
metaPartName
:=
strings
.
Replace
(
string
(
in
),
"{{"
,
""
,
1
)
metaPartName
:=
strings
.
Replace
(
string
(
in
),
"{{"
,
""
,
1
)
metaPartName
=
strings
.
Replace
(
metaPartName
,
"}}"
,
""
,
1
)
metaPartName
=
strings
.
Replace
(
metaPartName
,
"}}"
,
""
,
1
)
...
@@ -359,23 +370,15 @@ func formatAzureMonitorLegendKey(alias string, resourceName string, metricName s
...
@@ -359,23 +370,15 @@ func formatAzureMonitorLegendKey(alias string, resourceName string, metricName s
return
[]
byte
(
metricName
)
return
[]
byte
(
metricName
)
}
}
keys
:=
make
([]
string
,
0
,
len
(
labels
))
if
metaPartName
==
"dimensionname"
||
metaPartName
==
"dimensionvalue"
{
for
k
:=
range
labels
{
keys
=
append
(
keys
,
k
)
}
keys
=
sort
.
StringSlice
(
keys
)
}
if
metaPartName
==
"dimensionname"
{
if
metaPartName
==
"dimensionname"
{
return
[]
byte
(
keys
[
0
])
return
[]
byte
(
keys
[
0
])
}
}
if
metaPartName
==
"dimensionvalue"
{
if
metaPartName
==
"dimensionvalue"
{
return
[]
byte
(
labels
[
keys
[
0
]])
return
[]
byte
(
l
owerL
abels
[
keys
[
0
]])
}
}
if
v
,
ok
:=
labels
[
metaPartName
];
ok
{
if
v
,
ok
:=
l
owerL
abels
[
metaPartName
];
ok
{
return
[]
byte
(
v
)
return
[]
byte
(
v
)
}
}
return
in
return
in
...
...
pkg/tsdb/azuremonitor/azuremonitor-datasource_test.go
View file @
9164a352
...
@@ -374,7 +374,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
...
@@ -374,7 +374,7 @@ func TestAzureMonitorParseResponse(t *testing.T) {
name
:
"multiple dimension time series response with label alias"
,
name
:
"multiple dimension time series response with label alias"
,
responseFile
:
"7-azure-monitor-response-multi-dimension.json"
,
responseFile
:
"7-azure-monitor-response-multi-dimension.json"
,
mockQuery
:
&
AzureMonitorQuery
{
mockQuery
:
&
AzureMonitorQuery
{
Alias
:
"{{resourcegroup}} {Blob Type={{blobtype}}, Tier={{
t
ier}}}"
,
Alias
:
"{{resourcegroup}} {Blob Type={{blobtype}}, Tier={{
T
ier}}}"
,
UrlComponents
:
map
[
string
]
string
{
UrlComponents
:
map
[
string
]
string
{
"resourceName"
:
"grafana"
,
"resourceName"
:
"grafana"
,
},
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment