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
a08cbbcc
Unverified
Commit
a08cbbcc
authored
Apr 09, 2020
by
Carl Bergquist
Committed by
GitHub
Apr 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Instrument backend plugin requests (#23346)
parent
1f0e1b33
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
100 additions
and
23 deletions
+100
-23
pkg/infra/metrics/metrics.go
+0
-0
pkg/plugins/backendplugin/backend_plugin.go
+15
-2
pkg/plugins/backendplugin/instrumentation.go
+47
-0
pkg/plugins/backendplugin/manager.go
+30
-20
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_v2.go
+8
-1
No files found.
pkg/infra/metrics/metrics.go
View file @
a08cbbcc
This diff is collapsed.
Click to expand it.
pkg/plugins/backendplugin/backend_plugin.go
View file @
a08cbbcc
...
@@ -141,7 +141,14 @@ func (p *BackendPlugin) CollectMetrics(ctx context.Context) (*pluginv2.CollectMe
...
@@ -141,7 +141,14 @@ func (p *BackendPlugin) CollectMetrics(ctx context.Context) (*pluginv2.CollectMe
},
nil
},
nil
}
}
res
,
err
:=
p
.
diagnostics
.
CollectMetrics
(
ctx
,
&
pluginv2
.
CollectMetricsRequest
{})
var
res
*
pluginv2
.
CollectMetricsResponse
err
:=
InstrumentPluginRequest
(
p
.
id
,
"metrics"
,
func
()
error
{
var
innerErr
error
res
,
innerErr
=
p
.
diagnostics
.
CollectMetrics
(
ctx
,
&
pluginv2
.
CollectMetricsRequest
{})
return
innerErr
})
if
err
!=
nil
{
if
err
!=
nil
{
if
st
,
ok
:=
status
.
FromError
(
err
);
ok
{
if
st
,
ok
:=
status
.
FromError
(
err
);
ok
{
if
st
.
Code
()
==
codes
.
Unimplemented
{
if
st
.
Code
()
==
codes
.
Unimplemented
{
...
@@ -197,7 +204,13 @@ func (p *BackendPlugin) checkHealth(ctx context.Context, config *PluginConfig) (
...
@@ -197,7 +204,13 @@ func (p *BackendPlugin) checkHealth(ctx context.Context, config *PluginConfig) (
}
}
}
}
res
,
err
:=
p
.
diagnostics
.
CheckHealth
(
ctx
,
&
pluginv2
.
CheckHealthRequest
{
Config
:
pconfig
})
var
res
*
pluginv2
.
CheckHealthResponse
err
=
InstrumentPluginRequest
(
p
.
id
,
"checkhealth"
,
func
()
error
{
var
innerErr
error
res
,
innerErr
=
p
.
diagnostics
.
CheckHealth
(
ctx
,
&
pluginv2
.
CheckHealthRequest
{
Config
:
pconfig
})
return
innerErr
})
if
err
!=
nil
{
if
err
!=
nil
{
if
st
,
ok
:=
status
.
FromError
(
err
);
ok
{
if
st
,
ok
:=
status
.
FromError
(
err
);
ok
{
if
st
.
Code
()
==
codes
.
Unimplemented
{
if
st
.
Code
()
==
codes
.
Unimplemented
{
...
...
pkg/plugins/backendplugin/instrumentation.go
0 → 100644
View file @
a08cbbcc
package
backendplugin
import
(
"time"
"github.com/prometheus/client_golang/prometheus"
)
var
(
pluginRequestCounter
*
prometheus
.
CounterVec
pluginRequestDuration
*
prometheus
.
SummaryVec
)
func
init
()
{
pluginRequestCounter
=
prometheus
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Namespace
:
"grafana"
,
Name
:
"plugin_request_total"
,
Help
:
"The total amount of plugin requests"
,
},
[]
string
{
"plugin_id"
,
"endpoint"
,
"status"
})
pluginRequestDuration
=
prometheus
.
NewSummaryVec
(
prometheus
.
SummaryOpts
{
Namespace
:
"grafana"
,
Name
:
"plugin_request_duration_milliseconds"
,
Help
:
"Plugin request duration"
,
Objectives
:
map
[
float64
]
float64
{
0.5
:
0.05
,
0.9
:
0.01
,
0.99
:
0.001
},
},
[]
string
{
"plugin_id"
,
"endpoint"
})
prometheus
.
MustRegister
(
pluginRequestCounter
,
pluginRequestDuration
)
}
// InstrumentPluginRequest instruments success rate and latency of `fn`
func
InstrumentPluginRequest
(
pluginID
string
,
endpoint
string
,
fn
func
()
error
)
error
{
status
:=
"ok"
start
:=
time
.
Now
()
err
:=
fn
()
if
err
!=
nil
{
status
=
"error"
}
elapsed
:=
time
.
Since
(
start
)
/
time
.
Millisecond
pluginRequestDuration
.
WithLabelValues
(
pluginID
,
endpoint
)
.
Observe
(
float64
(
elapsed
))
pluginRequestCounter
.
WithLabelValues
(
pluginID
,
endpoint
,
status
)
.
Inc
()
return
err
}
pkg/plugins/backendplugin/manager.go
View file @
a08cbbcc
...
@@ -8,6 +8,7 @@ import (
...
@@ -8,6 +8,7 @@ import (
"time"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/util/errutil"
"github.com/grafana/grafana/pkg/util/proxyutil"
"github.com/grafana/grafana/pkg/util/proxyutil"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/log"
...
@@ -187,17 +188,17 @@ func (m *manager) CheckHealth(ctx context.Context, pluginConfig *PluginConfig) (
...
@@ -187,17 +188,17 @@ func (m *manager) CheckHealth(ctx context.Context, pluginConfig *PluginConfig) (
}
}
// CallResource calls a plugin resource.
// CallResource calls a plugin resource.
func
(
m
*
manager
)
CallResource
(
config
PluginConfig
,
c
*
models
.
ReqContext
,
path
string
)
{
func
(
m
*
manager
)
CallResource
(
config
PluginConfig
,
reqCtx
*
models
.
ReqContext
,
path
string
)
{
m
.
pluginsMu
.
RLock
()
m
.
pluginsMu
.
RLock
()
p
,
registered
:=
m
.
plugins
[
config
.
PluginID
]
p
,
registered
:=
m
.
plugins
[
config
.
PluginID
]
m
.
pluginsMu
.
RUnlock
()
m
.
pluginsMu
.
RUnlock
()
if
!
registered
{
if
!
registered
{
c
.
JsonApiErr
(
404
,
"Plugin not registered"
,
nil
)
reqCtx
.
JsonApiErr
(
404
,
"Plugin not registered"
,
nil
)
return
return
}
}
clonedReq
:=
c
.
Req
.
Clone
(
c
.
Req
.
Context
())
clonedReq
:=
reqCtx
.
Req
.
Clone
(
reqCtx
.
Req
.
Context
())
keepCookieNames
:=
[]
string
{}
keepCookieNames
:=
[]
string
{}
if
config
.
JSONData
!=
nil
{
if
config
.
JSONData
!=
nil
{
if
keepCookies
:=
config
.
JSONData
.
Get
(
"keepCookies"
);
keepCookies
!=
nil
{
if
keepCookies
:=
config
.
JSONData
.
Get
(
"keepCookies"
);
keepCookies
!=
nil
{
...
@@ -208,9 +209,9 @@ func (m *manager) CallResource(config PluginConfig, c *models.ReqContext, path s
...
@@ -208,9 +209,9 @@ func (m *manager) CallResource(config PluginConfig, c *models.ReqContext, path s
proxyutil
.
ClearCookieHeader
(
clonedReq
,
keepCookieNames
)
proxyutil
.
ClearCookieHeader
(
clonedReq
,
keepCookieNames
)
proxyutil
.
PrepareProxyRequest
(
clonedReq
)
proxyutil
.
PrepareProxyRequest
(
clonedReq
)
body
,
err
:=
c
.
Req
.
Body
()
.
Bytes
()
body
,
err
:=
reqCtx
.
Req
.
Body
()
.
Bytes
()
if
err
!=
nil
{
if
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Failed to read request body"
,
err
)
reqCtx
.
JsonApiErr
(
500
,
"Failed to read request body"
,
err
)
return
return
}
}
...
@@ -221,32 +222,41 @@ func (m *manager) CallResource(config PluginConfig, c *models.ReqContext, path s
...
@@ -221,32 +222,41 @@ func (m *manager) CallResource(config PluginConfig, c *models.ReqContext, path s
URL
:
clonedReq
.
URL
.
String
(),
URL
:
clonedReq
.
URL
.
String
(),
Headers
:
clonedReq
.
Header
,
Headers
:
clonedReq
.
Header
,
Body
:
body
,
Body
:
body
,
User
:
c
.
SignedInUser
,
User
:
reqCtx
.
SignedInUser
,
}
}
stream
,
err
:=
p
.
callResource
(
clonedReq
.
Context
(),
req
)
err
=
InstrumentPluginRequest
(
p
.
id
,
"resource"
,
func
()
error
{
stream
,
err
:=
p
.
callResource
(
clonedReq
.
Context
(),
req
)
if
err
!=
nil
{
return
errutil
.
Wrap
(
"Failed to call resource"
,
err
)
}
return
flushStream
(
p
,
stream
,
reqCtx
)
})
if
err
!=
nil
{
if
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Failed to call resource"
,
err
)
reqCtx
.
JsonApiErr
(
500
,
"Failed to "
,
err
)
return
}
}
}
func
flushStream
(
plugin
*
BackendPlugin
,
stream
callResourceResultStream
,
reqCtx
*
models
.
ReqContext
)
error
{
processedStreams
:=
0
processedStreams
:=
0
for
{
for
{
resp
,
err
:=
stream
.
Recv
()
resp
,
err
:=
stream
.
Recv
()
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
if
processedStreams
==
0
{
if
processedStreams
==
0
{
c
.
JsonApiErr
(
500
,
"Received empty resource response "
,
nil
)
return
errors
.
New
(
"Received empty resource response"
)
}
}
return
return
nil
}
}
if
err
!=
nil
{
if
err
!=
nil
{
if
processedStreams
==
0
{
if
processedStreams
==
0
{
c
.
JsonApiErr
(
500
,
"Failed to receive response from resource call"
,
err
)
return
errutil
.
Wrap
(
"Failed to receive response from resource call"
,
err
)
}
else
{
p
.
logger
.
Error
(
"Failed to receive response from resource call"
,
"error"
,
err
)
}
}
return
plugin
.
logger
.
Error
(
"Failed to receive response from resource call"
,
"error"
,
err
)
return
nil
}
}
// Expected that headers and status are only part of first stream
// Expected that headers and status are only part of first stream
...
@@ -264,18 +274,18 @@ func (m *manager) CallResource(config PluginConfig, c *models.ReqContext, path s
...
@@ -264,18 +274,18 @@ func (m *manager) CallResource(config PluginConfig, c *models.ReqContext, path s
}
}
for
_
,
v
:=
range
values
{
for
_
,
v
:=
range
values
{
c
.
Resp
.
Header
()
.
Add
(
k
,
v
)
reqCtx
.
Resp
.
Header
()
.
Add
(
k
,
v
)
}
}
}
}
c
.
WriteHeader
(
resp
.
Status
)
reqCtx
.
WriteHeader
(
resp
.
Status
)
}
}
if
_
,
err
:=
c
.
Write
(
resp
.
Body
);
err
!=
nil
{
if
_
,
err
:=
reqCtx
.
Write
(
resp
.
Body
);
err
!=
nil
{
p
.
logger
.
Error
(
"Failed to write resource response"
,
"error"
,
err
)
p
lugin
.
logger
.
Error
(
"Failed to write resource response"
,
"error"
,
err
)
}
}
c
.
Resp
.
Flush
()
reqCtx
.
Resp
.
Flush
()
processedStreams
++
processedStreams
++
}
}
}
}
...
...
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_v2.go
View file @
a08cbbcc
...
@@ -77,7 +77,14 @@ func (tw *DatasourcePluginWrapperV2) Query(ctx context.Context, ds *models.DataS
...
@@ -77,7 +77,14 @@ func (tw *DatasourcePluginWrapperV2) Query(ctx context.Context, ds *models.DataS
})
})
}
}
pbRes
,
err
:=
tw
.
DataPlugin
.
QueryData
(
ctx
,
pbQuery
)
var
pbRes
*
pluginv2
.
QueryDataResponse
err
=
backendplugin
.
InstrumentPluginRequest
(
ds
.
Type
,
"dataquery"
,
func
()
error
{
var
err
error
pbRes
,
err
=
tw
.
DataPlugin
.
QueryData
(
ctx
,
pbQuery
)
return
err
})
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
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