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
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
145 additions
and
67 deletions
+145
-67
pkg/infra/metrics/metrics.go
+45
-44
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
...
@@ -8,7 +8,8 @@ import (
...
@@ -8,7 +8,8 @@ import (
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/setting"
)
)
const
exporterName
=
"grafana"
// ExporterName is used as namespace for exposing prometheus metrics
const
ExporterName
=
"grafana"
var
(
var
(
// MInstanceStart is a metric counter for started instances
// MInstanceStart is a metric counter for started instances
...
@@ -159,28 +160,28 @@ func init() {
...
@@ -159,28 +160,28 @@ func init() {
MInstanceStart
=
prometheus
.
NewCounter
(
prometheus
.
CounterOpts
{
MInstanceStart
=
prometheus
.
NewCounter
(
prometheus
.
CounterOpts
{
Name
:
"instance_start_total"
,
Name
:
"instance_start_total"
,
Help
:
"counter for started instances"
,
Help
:
"counter for started instances"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MPageStatus
=
newCounterVecStartingAtZero
(
MPageStatus
=
newCounterVecStartingAtZero
(
prometheus
.
CounterOpts
{
prometheus
.
CounterOpts
{
Name
:
"page_response_status_total"
,
Name
:
"page_response_status_total"
,
Help
:
"page http response status"
,
Help
:
"page http response status"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"code"
},
httpStatusCodes
...
)
},
[]
string
{
"code"
},
httpStatusCodes
...
)
MApiStatus
=
newCounterVecStartingAtZero
(
MApiStatus
=
newCounterVecStartingAtZero
(
prometheus
.
CounterOpts
{
prometheus
.
CounterOpts
{
Name
:
"api_response_status_total"
,
Name
:
"api_response_status_total"
,
Help
:
"api http response status"
,
Help
:
"api http response status"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"code"
},
httpStatusCodes
...
)
},
[]
string
{
"code"
},
httpStatusCodes
...
)
MProxyStatus
=
newCounterVecStartingAtZero
(
MProxyStatus
=
newCounterVecStartingAtZero
(
prometheus
.
CounterOpts
{
prometheus
.
CounterOpts
{
Name
:
"proxy_response_status_total"
,
Name
:
"proxy_response_status_total"
,
Help
:
"proxy http response status"
,
Help
:
"proxy http response status"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"code"
},
httpStatusCodes
...
)
},
[]
string
{
"code"
},
httpStatusCodes
...
)
MHttpRequestTotal
=
prometheus
.
NewCounterVec
(
MHttpRequestTotal
=
prometheus
.
NewCounterVec
(
...
@@ -203,241 +204,241 @@ func init() {
...
@@ -203,241 +204,241 @@ func init() {
MApiUserSignUpStarted
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiUserSignUpStarted
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_user_signup_started_total"
,
Name
:
"api_user_signup_started_total"
,
Help
:
"amount of users who started the signup flow"
,
Help
:
"amount of users who started the signup flow"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiUserSignUpCompleted
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiUserSignUpCompleted
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_user_signup_completed_total"
,
Name
:
"api_user_signup_completed_total"
,
Help
:
"amount of users who completed the signup flow"
,
Help
:
"amount of users who completed the signup flow"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiUserSignUpInvite
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiUserSignUpInvite
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_user_signup_invite_total"
,
Name
:
"api_user_signup_invite_total"
,
Help
:
"amount of users who have been invited"
,
Help
:
"amount of users who have been invited"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiDashboardSave
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
MApiDashboardSave
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
Name
:
"api_dashboard_save_milliseconds"
,
Name
:
"api_dashboard_save_milliseconds"
,
Help
:
"summary for dashboard save duration"
,
Help
:
"summary for dashboard save duration"
,
Objectives
:
objectiveMap
,
Objectives
:
objectiveMap
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiDashboardGet
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
MApiDashboardGet
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
Name
:
"api_dashboard_get_milliseconds"
,
Name
:
"api_dashboard_get_milliseconds"
,
Help
:
"summary for dashboard get duration"
,
Help
:
"summary for dashboard get duration"
,
Objectives
:
objectiveMap
,
Objectives
:
objectiveMap
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiDashboardSearch
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
MApiDashboardSearch
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
Name
:
"api_dashboard_search_milliseconds"
,
Name
:
"api_dashboard_search_milliseconds"
,
Help
:
"summary for dashboard search duration"
,
Help
:
"summary for dashboard search duration"
,
Objectives
:
objectiveMap
,
Objectives
:
objectiveMap
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiAdminUserCreate
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiAdminUserCreate
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_admin_user_created_total"
,
Name
:
"api_admin_user_created_total"
,
Help
:
"api admin user created counter"
,
Help
:
"api admin user created counter"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiLoginPost
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiLoginPost
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_login_post_total"
,
Name
:
"api_login_post_total"
,
Help
:
"api login post counter"
,
Help
:
"api login post counter"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiLoginOAuth
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiLoginOAuth
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_login_oauth_total"
,
Name
:
"api_login_oauth_total"
,
Help
:
"api login oauth counter"
,
Help
:
"api login oauth counter"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiLoginSAML
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiLoginSAML
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_login_saml_total"
,
Name
:
"api_login_saml_total"
,
Help
:
"api login saml counter"
,
Help
:
"api login saml counter"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiOrgCreate
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiOrgCreate
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_org_create_total"
,
Name
:
"api_org_create_total"
,
Help
:
"api org created counter"
,
Help
:
"api org created counter"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiDashboardSnapshotCreate
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiDashboardSnapshotCreate
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_dashboard_snapshot_create_total"
,
Name
:
"api_dashboard_snapshot_create_total"
,
Help
:
"dashboard snapshots created"
,
Help
:
"dashboard snapshots created"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiDashboardSnapshotExternal
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiDashboardSnapshotExternal
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_dashboard_snapshot_external_total"
,
Name
:
"api_dashboard_snapshot_external_total"
,
Help
:
"external dashboard snapshots created"
,
Help
:
"external dashboard snapshots created"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiDashboardSnapshotGet
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiDashboardSnapshotGet
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_dashboard_snapshot_get_total"
,
Name
:
"api_dashboard_snapshot_get_total"
,
Help
:
"loaded dashboards"
,
Help
:
"loaded dashboards"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MApiDashboardInsert
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MApiDashboardInsert
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"api_models_dashboard_insert_total"
,
Name
:
"api_models_dashboard_insert_total"
,
Help
:
"dashboards inserted "
,
Help
:
"dashboards inserted "
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MAlertingResultState
=
prometheus
.
NewCounterVec
(
prometheus
.
CounterOpts
{
MAlertingResultState
=
prometheus
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"alerting_result_total"
,
Name
:
"alerting_result_total"
,
Help
:
"alert execution result counter"
,
Help
:
"alert execution result counter"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"state"
})
},
[]
string
{
"state"
})
MAlertingNotificationSent
=
prometheus
.
NewCounterVec
(
prometheus
.
CounterOpts
{
MAlertingNotificationSent
=
prometheus
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"alerting_notification_sent_total"
,
Name
:
"alerting_notification_sent_total"
,
Help
:
"counter for how many alert notifications have been sent"
,
Help
:
"counter for how many alert notifications have been sent"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"type"
})
},
[]
string
{
"type"
})
MAlertingNotificationFailed
=
prometheus
.
NewCounterVec
(
prometheus
.
CounterOpts
{
MAlertingNotificationFailed
=
prometheus
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"alerting_notification_failed_total"
,
Name
:
"alerting_notification_failed_total"
,
Help
:
"counter for how many alert notifications have failed"
,
Help
:
"counter for how many alert notifications have failed"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"type"
})
},
[]
string
{
"type"
})
MAwsCloudWatchGetMetricStatistics
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MAwsCloudWatchGetMetricStatistics
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"aws_cloudwatch_get_metric_statistics_total"
,
Name
:
"aws_cloudwatch_get_metric_statistics_total"
,
Help
:
"counter for getting metric statistics from aws"
,
Help
:
"counter for getting metric statistics from aws"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MAwsCloudWatchListMetrics
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MAwsCloudWatchListMetrics
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"aws_cloudwatch_list_metrics_total"
,
Name
:
"aws_cloudwatch_list_metrics_total"
,
Help
:
"counter for getting list of metrics from aws"
,
Help
:
"counter for getting list of metrics from aws"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MAwsCloudWatchGetMetricData
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MAwsCloudWatchGetMetricData
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"aws_cloudwatch_get_metric_data_total"
,
Name
:
"aws_cloudwatch_get_metric_data_total"
,
Help
:
"counter for getting metric data time series from aws"
,
Help
:
"counter for getting metric data time series from aws"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MDBDataSourceQueryByID
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
MDBDataSourceQueryByID
=
newCounterStartingAtZero
(
prometheus
.
CounterOpts
{
Name
:
"db_datasource_query_by_id_total"
,
Name
:
"db_datasource_query_by_id_total"
,
Help
:
"counter for getting datasource by id"
,
Help
:
"counter for getting datasource by id"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
LDAPUsersSyncExecutionTime
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
LDAPUsersSyncExecutionTime
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
Name
:
"ldap_users_sync_execution_time"
,
Name
:
"ldap_users_sync_execution_time"
,
Help
:
"summary for LDAP users sync execution duration"
,
Help
:
"summary for LDAP users sync execution duration"
,
Objectives
:
objectiveMap
,
Objectives
:
objectiveMap
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MDataSourceProxyReqTimer
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
MDataSourceProxyReqTimer
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
Name
:
"api_dataproxy_request_all_milliseconds"
,
Name
:
"api_dataproxy_request_all_milliseconds"
,
Help
:
"summary for dataproxy request duration"
,
Help
:
"summary for dataproxy request duration"
,
Objectives
:
objectiveMap
,
Objectives
:
objectiveMap
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MAlertingExecutionTime
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
MAlertingExecutionTime
=
prometheus
.
NewSummary
(
prometheus
.
SummaryOpts
{
Name
:
"alerting_execution_time_milliseconds"
,
Name
:
"alerting_execution_time_milliseconds"
,
Help
:
"summary of alert exeuction duration"
,
Help
:
"summary of alert exeuction duration"
,
Objectives
:
objectiveMap
,
Objectives
:
objectiveMap
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MAlertingActiveAlerts
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
MAlertingActiveAlerts
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"alerting_active_alerts"
,
Name
:
"alerting_active_alerts"
,
Help
:
"amount of active alerts"
,
Help
:
"amount of active alerts"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MStatTotalDashboards
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
MStatTotalDashboards
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_totals_dashboard"
,
Name
:
"stat_totals_dashboard"
,
Help
:
"total amount of dashboards"
,
Help
:
"total amount of dashboards"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MStatTotalUsers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
MStatTotalUsers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_total_users"
,
Name
:
"stat_total_users"
,
Help
:
"total amount of users"
,
Help
:
"total amount of users"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MStatActiveUsers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
MStatActiveUsers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_active_users"
,
Name
:
"stat_active_users"
,
Help
:
"number of active users"
,
Help
:
"number of active users"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MStatTotalOrgs
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
MStatTotalOrgs
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_total_orgs"
,
Name
:
"stat_total_orgs"
,
Help
:
"total amount of orgs"
,
Help
:
"total amount of orgs"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
MStatTotalPlaylists
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
MStatTotalPlaylists
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_total_playlists"
,
Name
:
"stat_total_playlists"
,
Help
:
"total amount of playlists"
,
Help
:
"total amount of playlists"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
StatsTotalViewers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
StatsTotalViewers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_totals_viewers"
,
Name
:
"stat_totals_viewers"
,
Help
:
"total amount of viewers"
,
Help
:
"total amount of viewers"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
StatsTotalEditors
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
StatsTotalEditors
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_totals_editors"
,
Name
:
"stat_totals_editors"
,
Help
:
"total amount of editors"
,
Help
:
"total amount of editors"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
StatsTotalAdmins
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
StatsTotalAdmins
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_totals_admins"
,
Name
:
"stat_totals_admins"
,
Help
:
"total amount of admins"
,
Help
:
"total amount of admins"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
StatsTotalActiveViewers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
StatsTotalActiveViewers
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_totals_active_viewers"
,
Name
:
"stat_totals_active_viewers"
,
Help
:
"total amount of viewers"
,
Help
:
"total amount of viewers"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
StatsTotalActiveEditors
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
StatsTotalActiveEditors
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_totals_active_editors"
,
Name
:
"stat_totals_active_editors"
,
Help
:
"total amount of active editors"
,
Help
:
"total amount of active editors"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
StatsTotalActiveAdmins
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
StatsTotalActiveAdmins
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"stat_totals_active_admins"
,
Name
:
"stat_totals_active_admins"
,
Help
:
"total amount of active admins"
,
Help
:
"total amount of active admins"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
})
})
grafanaBuildVersion
=
prometheus
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
grafanaBuildVersion
=
prometheus
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Name
:
"build_info"
,
Name
:
"build_info"
,
Help
:
"A metric with a constant '1' value labeled by version, revision, branch, and goversion from which Grafana was built"
,
Help
:
"A metric with a constant '1' value labeled by version, revision, branch, and goversion from which Grafana was built"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"version"
,
"revision"
,
"branch"
,
"goversion"
,
"edition"
})
},
[]
string
{
"version"
,
"revision"
,
"branch"
,
"goversion"
,
"edition"
})
grafanPluginBuildInfoDesc
=
prometheus
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
grafanPluginBuildInfoDesc
=
prometheus
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Name
:
"plugin_build_info"
,
Name
:
"plugin_build_info"
,
Help
:
"A metric with a constant '1' value labeled by pluginId, pluginType and version from which Grafana plugin was built"
,
Help
:
"A metric with a constant '1' value labeled by pluginId, pluginType and version from which Grafana plugin was built"
,
Namespace
:
e
xporterName
,
Namespace
:
E
xporterName
,
},
[]
string
{
"plugin_id"
,
"plugin_type"
,
"version"
})
},
[]
string
{
"plugin_id"
,
"plugin_type"
,
"version"
})
}
}
...
...
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