使用 OpenTelemetry 的 .NET 可觀測性

小良哥發表於2024-03-09

參考文件 https://learn.microsoft.com/zh-cn/dotnet/core/diagnostics/observability-with-otel

1,安裝prometheus

配置檔案可以先使用docker建立一個預設的,然後複製出新的配置檔案

使用 OpenTelemetry 的 .NET 可觀測性
1 docker run -d --name prometheus -p 9090:9090 prom/prometheus
2 docker cp prometheus:/etc/prometheus/prometheus.yml /docker/prometheus/server/prometheus.yml
View Code

配置檔案如下:

使用 OpenTelemetry 的 .NET 可觀測性
 1 # my global config
 2 global:
 3   scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
 4   evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
 5   # scrape_timeout is set to the global default (10s).
 6 
 7 # Alertmanager configuration
 8 alerting:
 9   alertmanagers:
10     - static_configs:
11         - targets:
12           # - alertmanager:9093
13 
14 # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
15 rule_files:
16   # - "first_rules.yml"
17   # - "second_rules.yml"
18 
19 # A scrape configuration containing exactly one endpoint to scrape:
20 # Here it's Prometheus itself.
21 scrape_configs:
22   # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
23   - job_name: "prometheus"
24 
25     # metrics_path defaults to '/metrics'
26     # scheme defaults to 'http'.
27 
28     static_configs:
29       - targets: ["47.119.162.152:8001","192.168.0.204:8001"]
30 #global:全域性配置 (如果有內部單獨設定,會覆蓋這個引數)
31 #alerting:告警外掛定義。這裡會設定alertmanager這個報警外掛
32 #rule_files:告警規則。 按照設定引數進行掃描載入,用於自定義報警規則,其報警媒介和route路由由alertmanager外掛實現
33 #scrape_configs:採集配置。配置資料來源,包含分組job_name以及具體target。又分為靜態配置和服務發現
34 #remote_write:用於遠端儲存寫配置
35 #remote_read:用於遠端讀配置
View Code

docker執行命令:

使用 OpenTelemetry 的 .NET 可觀測性
1 docker run -d --name prometheus -p 9090:9090 --restart=always \
2 -v /docker/prometheus/server/prometheus.yml:/etc/prometheus/prometheus.yml \
3 -v /docker/prometheus/server/rules.yml:/etc/prometheus/rules.yml \
4  -v /etc/localtime:/etc/localtime:ro \
5     -v /docker/prometheus/server/data:/prometheus/data \
6     -v /docker/prometheus/server/config:/prometheus/config \
7     -v /docker/prometheus/server/rules:/prometheus/rules \
8     -v /docker/prometheus/server/ClientAll:/prometheus/ClientAll \
9 prom/prometheus --config.file=/etc/prometheus/prometheus.yml --web.enable-lifecycle
View Code

2,安裝grafana

配置檔案可以先使用docker建立一個預設的,然後複製出新的配置檔案

使用 OpenTelemetry 的 .NET 可觀測性
 1 docker cp grafana-tmp:/etc/grafana/grafana.ini /docker/grafana/config/grafana.ini
 2 
 3 docker run -d --name grafana -p 3000:3000 --restart=always \
 4     -v /etc/localtime:/etc/localtime:ro \
 5     -v /docker/grafana/data:/var/lib/grafana \
 6     -v /docker/grafana/plugins/:/var/lib/grafana/plugins \
 7     -v /docker/grafana/config/grafana.ini:/etc/grafana/grafana.ini \
 8     -e "GF_SECURITY_ADMIN_PASSWORD=admin" \
 9     grafana/grafana
10 
11     -e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource,natel-discrete-panel,grafana-piechart-panel" \
View Code

配置檔案如下:

使用 OpenTelemetry 的 .NET 可觀測性
   1 ##################### Grafana Configuration Example #####################
   2 #
   3 # Everything has defaults so you only need to uncomment things you want to
   4 # change
   5 
   6 # possible values : production, development
   7 ;app_mode = production
   8 
   9 # instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
  10 ;instance_name = ${HOSTNAME}
  11 
  12 #################################### Paths ####################################
  13 [paths]
  14 # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
  15 ;data = /var/lib/grafana
  16 
  17 # Temporary files in `data` directory older than given duration will be removed
  18 ;temp_data_lifetime = 24h
  19 
  20 # Directory where grafana can store logs
  21 ;logs = /var/log/grafana
  22 
  23 # Directory where grafana will automatically scan and look for plugins
  24 ;plugins = /var/lib/grafana/plugins
  25 
  26 # folder that contains provisioning config files that grafana will apply on startup and while running.
  27 ;provisioning = conf/provisioning
  28 
  29 #################################### Server ####################################
  30 [server]
  31 # Protocol (http, https, h2, socket)
  32 ;protocol = http
  33 
  34 # The ip address to bind to, empty will bind to all interfaces
  35 ;http_addr =
  36 
  37 # The http port  to use
  38 ;http_port = 3000
  39 
  40 # The public facing domain name used to access grafana from a browser
  41 ;domain = localhost
  42 
  43 # Redirect to correct domain if host header does not match domain
  44 # Prevents DNS rebinding attacks
  45 ;enforce_domain = false
  46 
  47 # The full public facing url you use in browser, used for redirects and emails
  48 # If you use reverse proxy and sub path specify full url (with sub path)
  49 ;root_url = %(protocol)s://%(domain)s:%(http_port)s/
  50 
  51 # Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
  52 ;serve_from_sub_path = false
  53 
  54 # Log web requests
  55 ;router_logging = false
  56 
  57 # the path relative working path
  58 ;static_root_path = public
  59 
  60 # enable gzip
  61 ;enable_gzip = false
  62 
  63 # https certs & key file
  64 ;cert_file =
  65 ;cert_key =
  66 
  67 # Unix socket path
  68 ;socket =
  69 
  70 # CDN Url
  71 ;cdn_url =
  72 
  73 # Sets the maximum time using a duration format (5s/5m/5ms) before timing out read of an incoming request and closing idle connections.
  74 # `0` means there is no timeout for reading the request.
  75 ;read_timeout = 0
  76 
  77 #################################### Database ####################################
  78 [database]
  79 # You can configure the database connection by specifying type, host, name, user and password
  80 # as separate properties or as on string using the url properties.
  81 
  82 # Either "mysql", "postgres" or "sqlite3", it's your choice
  83 ;type = sqlite3
  84 ;host = 127.0.0.1:3306
  85 ;name = grafana
  86 ;user = root
  87 # If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
  88 ;password =
  89 
  90 # Use either URL or the previous fields to configure the database
  91 # Example: mysql://user:secret@host:port/database
  92 ;url =
  93 
  94 # For "postgres" only, either "disable", "require" or "verify-full"
  95 ;ssl_mode = disable
  96 
  97 # Database drivers may support different transaction isolation levels.
  98 # Currently, only "mysql" driver supports isolation levels.
  99 # If the value is empty - driver's default isolation level is applied.
 100 # For "mysql" use "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ" or "SERIALIZABLE".
 101 ;isolation_level =
 102 
 103 ;ca_cert_path =
 104 ;client_key_path =
 105 ;client_cert_path =
 106 ;server_cert_name =
 107 
 108 # For "sqlite3" only, path relative to data_path setting
 109 ;path = grafana.db
 110 
 111 # Max idle conn setting default is 2
 112 ;max_idle_conn = 2
 113 
 114 # Max conn setting default is 0 (mean not set)
 115 ;max_open_conn =
 116 
 117 # Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
 118 ;conn_max_lifetime = 14400
 119 
 120 # Set to true to log the sql calls and execution times.
 121 ;log_queries =
 122 
 123 # For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared)
 124 ;cache_mode = private
 125 
 126 ################################### Data sources #########################
 127 [datasources]
 128 # Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API.
 129 ;datasource_limit = 5000
 130 
 131 #################################### Cache server #############################
 132 [remote_cache]
 133 # Either "redis", "memcached" or "database" default is "database"
 134 ;type = database
 135 
 136 # cache connectionstring options
 137 # database: will use Grafana primary database.
 138 # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
 139 # memcache: 127.0.0.1:11211
 140 ;connstr =
 141 
 142 #################################### Data proxy ###########################
 143 [dataproxy]
 144 
 145 # This enables data proxy logging, default is false
 146 ;logging = false
 147 
 148 # How long the data proxy waits to read the headers of the response before timing out, default is 30 seconds.
 149 # This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
 150 ;timeout = 30
 151 
 152 # How long the data proxy waits to establish a TCP connection before timing out, default is 10 seconds.
 153 ;dialTimeout = 10
 154 
 155 # How many seconds the data proxy waits before sending a keepalive probe request.
 156 ;keep_alive_seconds = 30
 157 
 158 # How many seconds the data proxy waits for a successful TLS Handshake before timing out.
 159 ;tls_handshake_timeout_seconds = 10
 160 
 161 # How many seconds the data proxy will wait for a server's first response headers after
 162 # fully writing the request headers if the request has an "Expect: 100-continue"
 163 # header. A value of 0 will result in the body being sent immediately, without
 164 # waiting for the server to approve.
 165 ;expect_continue_timeout_seconds = 1
 166 
 167 # Optionally limits the total number of connections per host, including connections in the dialing,
 168 # active, and idle states. On limit violation, dials will block.
 169 # A value of zero (0) means no limit.
 170 ;max_conns_per_host = 0
 171 
 172 # The maximum number of idle connections that Grafana will keep alive.
 173 ;max_idle_connections = 100
 174 
 175 # How many seconds the data proxy keeps an idle connection open before timing out.
 176 ;idle_conn_timeout_seconds = 90
 177 
 178 # If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false.
 179 ;send_user_header = false
 180 
 181 # Limit the amount of bytes that will be read/accepted from responses of outgoing HTTP requests.
 182 ;response_limit = 0
 183 
 184 # Limits the number of rows that Grafana will process from SQL data sources.
 185 ;row_limit = 1000000
 186 
 187 #################################### Analytics ####################################
 188 [analytics]
 189 # Server reporting, sends usage counters to stats.grafana.org every 24 hours.
 190 # No ip addresses are being tracked, only simple counters to track
 191 # running instances, dashboard and error counts. It is very helpful to us.
 192 # Change this option to false to disable reporting.
 193 ;reporting_enabled = true
 194 
 195 # The name of the distributor of the Grafana instance. Ex hosted-grafana, grafana-labs
 196 ;reporting_distributor = grafana-labs
 197 
 198 # Set to false to disable all checks to https://grafana.net
 199 # for new versions (grafana itself and plugins), check is used
 200 # in some UI views to notify that grafana or plugin update exists
 201 # This option does not cause any auto updates, nor send any information
 202 # only a GET request to http://grafana.com to get latest versions
 203 ;check_for_updates = true
 204 
 205 # Google Analytics universal tracking code, only enabled if you specify an id here
 206 ;google_analytics_ua_id =
 207 
 208 # Google Tag Manager ID, only enabled if you specify an id here
 209 ;google_tag_manager_id =
 210 
 211 #################################### Security ####################################
 212 [security]
 213 # disable creation of admin user on first start of grafana
 214 ;disable_initial_admin_creation = false
 215 
 216 # default admin user, created on startup
 217 ;admin_user = admin
 218 
 219 # default admin password, can be changed before first start of grafana,  or in profile settings
 220 ;admin_password = admin
 221 
 222 # used for signing
 223 ;secret_key = SW2YcwTIb9zpOOhoPsMm
 224 
 225 # current key provider used for envelope encryption, default to static value specified by secret_key
 226 ;encryption_provider = secretKey
 227 
 228 # list of configured key providers, space separated (Enterprise only): e.g., awskms.v1 azurekv.v1
 229 ;available_encryption_providers =
 230 
 231 # disable gravatar profile images
 232 ;disable_gravatar = false
 233 
 234 # data source proxy whitelist (ip_or_domain:port separated by spaces)
 235 ;data_source_proxy_whitelist =
 236 
 237 # disable protection against brute force login attempts
 238 ;disable_brute_force_login_protection = false
 239 
 240 # set to true if you host Grafana behind HTTPS. default is false.
 241 ;cookie_secure = false
 242 
 243 # set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
 244 ;cookie_samesite = lax
 245 
 246 # set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
 247 ;allow_embedding = false
 248 
 249 # Set to true if you want to enable http strict transport security (HSTS) response header.
 250 # This is only sent when HTTPS is enabled in this configuration.
 251 # HSTS tells browsers that the site should only be accessed using HTTPS.
 252 ;strict_transport_security = false
 253 
 254 # Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled.
 255 ;strict_transport_security_max_age_seconds = 86400
 256 
 257 # Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled.
 258 ;strict_transport_security_preload = false
 259 
 260 # Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled.
 261 ;strict_transport_security_subdomains = false
 262 
 263 # Set to true to enable the X-Content-Type-Options response header.
 264 # The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised
 265 # in the Content-Type headers should not be changed and be followed.
 266 ;x_content_type_options = true
 267 
 268 # Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading
 269 # when they detect reflected cross-site scripting (XSS) attacks.
 270 ;x_xss_protection = true
 271 
 272 # Enable adding the Content-Security-Policy header to your requests.
 273 # CSP allows to control resources the user agent is allowed to load and helps prevent XSS attacks.
 274 ;content_security_policy = false
 275 
 276 # Set Content Security Policy template used when adding the Content-Security-Policy header to your requests.
 277 # $NONCE in the template includes a random nonce.
 278 # $ROOT_PATH is server.root_url without the protocol.
 279 ;content_security_policy_template = """script-src 'self' 'unsafe-eval' 'unsafe-inline' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline' blob:;img-src * data:;base-uri 'self';connect-src 'self' grafana.com ws://$ROOT_PATH wss://$ROOT_PATH;manifest-src 'self';media-src 'none';form-action 'self';"""
 280 
 281 #################################### Snapshots ###########################
 282 [snapshots]
 283 # snapshot sharing options
 284 ;external_enabled = true
 285 ;external_snapshot_url = https://snapshots-origin.raintank.io
 286 ;external_snapshot_name = Publish to snapshot.raintank.io
 287 
 288 # Set to true to enable this Grafana instance act as an external snapshot server and allow unauthenticated requests for
 289 # creating and deleting snapshots.
 290 ;public_mode = false
 291 
 292 # remove expired snapshot
 293 ;snapshot_remove_expired = true
 294 
 295 #################################### Dashboards History ##################
 296 [dashboards]
 297 # Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
 298 ;versions_to_keep = 20
 299 
 300 # Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
 301 # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 302 ;min_refresh_interval = 5s
 303 
 304 # Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
 305 ;default_home_dashboard_path =
 306 
 307 #################################### Users ###############################
 308 [users]
 309 # disable user signup / registration
 310 ;allow_sign_up = true
 311 
 312 # Allow non admin users to create organizations
 313 ;allow_org_create = true
 314 
 315 # Set to true to automatically assign new users to the default organization (id 1)
 316 ;auto_assign_org = true
 317 
 318 # Set this value to automatically add new users to the provided organization (if auto_assign_org above is set to true)
 319 ;auto_assign_org_id = 1
 320 
 321 # Default role new users will be automatically assigned (if disabled above is set to true)
 322 ;auto_assign_org_role = Viewer
 323 
 324 # Require email validation before sign up completes
 325 ;verify_email_enabled = false
 326 
 327 # Background text for the user field on the login page
 328 ;login_hint = email or username
 329 ;password_hint = password
 330 
 331 # Default UI theme ("dark" or "light")
 332 ;default_theme = dark
 333 
 334 # Path to a custom home page. Users are only redirected to this if the default home dashboard is used. It should match a frontend route and contain a leading slash.
 335 ; home_page =
 336 
 337 # External user management, these options affect the organization users view
 338 ;external_manage_link_url =
 339 ;external_manage_link_name =
 340 ;external_manage_info =
 341 
 342 # Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
 343 ;viewers_can_edit = false
 344 
 345 # Editors can administrate dashboard, folders and teams they create
 346 ;editors_can_admin = false
 347 
 348 # The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes).
 349 ;user_invite_max_lifetime_duration = 24h
 350 
 351 # Enter a comma-separated list of users login to hide them in the Grafana UI. These users are shown to Grafana admins and themselves.
 352 ; hidden_users =
 353 
 354 [auth]
 355 # Login cookie name
 356 ;login_cookie_name = grafana_session
 357 
 358 # The maximum lifetime (duration) an authenticated user can be inactive before being required to login at next visit. Default is 7 days (7d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). The lifetime resets at each successful token rotation.
 359 ;login_maximum_inactive_lifetime_duration =
 360 
 361 # The maximum lifetime (duration) an authenticated user can be logged in since login time before being required to login. Default is 30 days (30d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month).
 362 ;login_maximum_lifetime_duration =
 363 
 364 # How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes.
 365 ;token_rotation_interval_minutes = 10
 366 
 367 # Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false
 368 ;disable_login_form = false
 369 
 370 # Set to true to disable the sign out link in the side menu. Useful if you use auth.proxy or auth.jwt, defaults to false
 371 ;disable_signout_menu = false
 372 
 373 # URL to redirect the user to after sign out
 374 ;signout_redirect_url =
 375 
 376 # Set to true to attempt login with OAuth automatically, skipping the login screen.
 377 # This setting is ignored if multiple OAuth providers are configured.
 378 ;oauth_auto_login = false
 379 
 380 # OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
 381 ;oauth_state_cookie_max_age = 600
 382 
 383 # limit of api_key seconds to live before expiration
 384 ;api_key_max_seconds_to_live = -1
 385 
 386 # Set to true to enable SigV4 authentication option for HTTP-based datasources.
 387 ;sigv4_auth_enabled = false
 388 
 389 #################################### Anonymous Auth ######################
 390 [auth.anonymous]
 391 # enable anonymous access
 392 ;enabled = false
 393 
 394 # specify organization name that should be used for unauthenticated users
 395 ;org_name = Main Org.
 396 
 397 # specify role for unauthenticated users
 398 ;org_role = Viewer
 399 
 400 # mask the Grafana version number for unauthenticated users
 401 ;hide_version = false
 402 
 403 #################################### GitHub Auth ##########################
 404 [auth.github]
 405 ;enabled = false
 406 ;allow_sign_up = true
 407 ;client_id = some_id
 408 ;client_secret = some_secret
 409 ;scopes = user:email,read:org
 410 ;auth_url = https://github.com/login/oauth/authorize
 411 ;token_url = https://github.com/login/oauth/access_token
 412 ;api_url = https://api.github.com/user
 413 ;allowed_domains =
 414 ;team_ids =
 415 ;allowed_organizations =
 416 
 417 #################################### GitLab Auth #########################
 418 [auth.gitlab]
 419 ;enabled = false
 420 ;allow_sign_up = true
 421 ;client_id = some_id
 422 ;client_secret = some_secret
 423 ;scopes = api
 424 ;auth_url = https://gitlab.com/oauth/authorize
 425 ;token_url = https://gitlab.com/oauth/token
 426 ;api_url = https://gitlab.com/api/v4
 427 ;allowed_domains =
 428 ;allowed_groups =
 429 
 430 #################################### Google Auth ##########################
 431 [auth.google]
 432 ;enabled = false
 433 ;allow_sign_up = true
 434 ;client_id = some_client_id
 435 ;client_secret = some_client_secret
 436 ;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
 437 ;auth_url = https://accounts.google.com/o/oauth2/auth
 438 ;token_url = https://accounts.google.com/o/oauth2/token
 439 ;api_url = https://www.googleapis.com/oauth2/v1/userinfo
 440 ;allowed_domains =
 441 ;hosted_domain =
 442 
 443 #################################### Grafana.com Auth ####################
 444 [auth.grafana_com]
 445 ;enabled = false
 446 ;allow_sign_up = true
 447 ;client_id = some_id
 448 ;client_secret = some_secret
 449 ;scopes = user:email
 450 ;allowed_organizations =
 451 
 452 #################################### Azure AD OAuth #######################
 453 [auth.azuread]
 454 ;name = Azure AD
 455 ;enabled = false
 456 ;allow_sign_up = true
 457 ;client_id = some_client_id
 458 ;client_secret = some_client_secret
 459 ;scopes = openid email profile
 460 ;auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
 461 ;token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
 462 ;allowed_domains =
 463 ;allowed_groups =
 464 
 465 #################################### Okta OAuth #######################
 466 [auth.okta]
 467 ;name = Okta
 468 ;enabled = false
 469 ;allow_sign_up = true
 470 ;client_id = some_id
 471 ;client_secret = some_secret
 472 ;scopes = openid profile email groups
 473 ;auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
 474 ;token_url = https://<tenant-id>.okta.com/oauth2/v1/token
 475 ;api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
 476 ;allowed_domains =
 477 ;allowed_groups =
 478 ;role_attribute_path =
 479 ;role_attribute_strict = false
 480 
 481 #################################### Generic OAuth ##########################
 482 [auth.generic_oauth]
 483 ;enabled = false
 484 ;name = OAuth
 485 ;allow_sign_up = true
 486 ;client_id = some_id
 487 ;client_secret = some_secret
 488 ;scopes = user:email,read:org
 489 ;empty_scopes = false
 490 ;email_attribute_name = email:primary
 491 ;email_attribute_path =
 492 ;login_attribute_path =
 493 ;name_attribute_path =
 494 ;id_token_attribute_name =
 495 ;auth_url = https://foo.bar/login/oauth/authorize
 496 ;token_url = https://foo.bar/login/oauth/access_token
 497 ;api_url = https://foo.bar/user
 498 ;teams_url =
 499 ;allowed_domains =
 500 ;team_ids =
 501 ;allowed_organizations =
 502 ;role_attribute_path =
 503 ;role_attribute_strict = false
 504 ;groups_attribute_path =
 505 ;team_ids_attribute_path =
 506 ;tls_skip_verify_insecure = false
 507 ;tls_client_cert =
 508 ;tls_client_key =
 509 ;tls_client_ca =
 510 ;use_pkce = false
 511 
 512 #################################### Basic Auth ##########################
 513 [auth.basic]
 514 ;enabled = true
 515 
 516 #################################### Auth Proxy ##########################
 517 [auth.proxy]
 518 ;enabled = false
 519 ;header_name = X-WEBAUTH-USER
 520 ;header_property = username
 521 ;auto_sign_up = true
 522 ;sync_ttl = 60
 523 ;whitelist = 192.168.1.1, 192.168.2.1
 524 ;headers = Email:X-User-Email, Name:X-User-Name
 525 # Read the auth proxy docs for details on what the setting below enables
 526 ;enable_login_token = false
 527 
 528 #################################### Auth JWT ##########################
 529 [auth.jwt]
 530 ;enabled = true
 531 ;header_name = X-JWT-Assertion
 532 ;email_claim = sub
 533 ;username_claim = sub
 534 ;jwk_set_url = https://foo.bar/.well-known/jwks.json
 535 ;jwk_set_file = /path/to/jwks.json
 536 ;cache_ttl = 60m
 537 ;expected_claims = {"aud": ["foo", "bar"]}
 538 ;key_file = /path/to/key/file
 539 
 540 #################################### Auth LDAP ##########################
 541 [auth.ldap]
 542 ;enabled = false
 543 ;config_file = /etc/grafana/ldap.toml
 544 ;allow_sign_up = true
 545 
 546 # LDAP background sync (Enterprise only)
 547 # At 1 am every day
 548 ;sync_cron = "0 0 1 * * *"
 549 ;active_sync_enabled = true
 550 
 551 #################################### AWS ###########################
 552 [aws]
 553 # Enter a comma-separated list of allowed AWS authentication providers.
 554 # Options are: default (AWS SDK Default), keys (Access && secret key), credentials (Credentials field), ec2_iam_role (EC2 IAM Role)
 555 ; allowed_auth_providers = default,keys,credentials
 556 
 557 # Allow AWS users to assume a role using temporary security credentials.
 558 # If true, assume role will be enabled for all AWS authentication providers that are specified in aws_auth_providers
 559 ; assume_role_enabled = true
 560 
 561 #################################### Azure ###############################
 562 [azure]
 563 # Azure cloud environment where Grafana is hosted
 564 # Possible values are AzureCloud, AzureChinaCloud, AzureUSGovernment and AzureGermanCloud
 565 # Default value is AzureCloud (i.e. public cloud)
 566 ;cloud = AzureCloud
 567 
 568 # Specifies whether Grafana hosted in Azure service with Managed Identity configured (e.g. Azure Virtual Machines instance)
 569 # If enabled, the managed identity can be used for authentication of Grafana in Azure services
 570 # Disabled by default, needs to be explicitly enabled
 571 ;managed_identity_enabled = false
 572 
 573 # Client ID to use for user-assigned managed identity
 574 # Should be set for user-assigned identity and should be empty for system-assigned identity
 575 ;managed_identity_client_id =
 576 
 577 #################################### SMTP / Emailing ##########################
 578 [smtp]
 579 ;enabled = false
 580 ;host = localhost:25
 581 ;user =
 582 # If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
 583 ;password =
 584 ;cert_file =
 585 ;key_file =
 586 ;skip_verify = false
 587 ;from_address = admin@grafana.localhost
 588 ;from_name = Grafana
 589 # EHLO identity in SMTP dialog (defaults to instance_name)
 590 ;ehlo_identity = dashboard.example.com
 591 # SMTP startTLS policy (defaults to 'OpportunisticStartTLS')
 592 ;startTLS_policy = NoStartTLS
 593 
 594 [emails]
 595 ;welcome_email_on_sign_up = false
 596 ;templates_pattern = emails/*.html, emails/*.txt
 597 ;content_types = text/html
 598 
 599 #################################### Logging ##########################
 600 [log]
 601 # Either "console", "file", "syslog". Default is console and  file
 602 # Use space to separate multiple modes, e.g. "console file"
 603 ;mode = console file
 604 
 605 # Either "debug", "info", "warn", "error", "critical", default is "info"
 606 ;level = info
 607 
 608 # optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
 609 ;filters =
 610 
 611 # For "console" mode only
 612 [log.console]
 613 ;level =
 614 
 615 # log line format, valid options are text, console and json
 616 ;format = console
 617 
 618 # For "file" mode only
 619 [log.file]
 620 ;level =
 621 
 622 # log line format, valid options are text, console and json
 623 ;format = text
 624 
 625 # This enables automated log rotate(switch of following options), default is true
 626 ;log_rotate = true
 627 
 628 # Max line number of single file, default is 1000000
 629 ;max_lines = 1000000
 630 
 631 # Max size shift of single file, default is 28 means 1 << 28, 256MB
 632 ;max_size_shift = 28
 633 
 634 # Segment log daily, default is true
 635 ;daily_rotate = true
 636 
 637 # Expired days of log file(delete after max days), default is 7
 638 ;max_days = 7
 639 
 640 [log.syslog]
 641 ;level =
 642 
 643 # log line format, valid options are text, console and json
 644 ;format = text
 645 
 646 # Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
 647 ;network =
 648 ;address =
 649 
 650 # Syslog facility. user, daemon and local0 through local7 are valid.
 651 ;facility =
 652 
 653 # Syslog tag. By default, the process' argv[0] is used.
 654 ;tag =
 655 
 656 [log.frontend]
 657 # Should Sentry javascript agent be initialized
 658 ;enabled = false
 659 
 660 # Sentry DSN if you want to send events to Sentry.
 661 ;sentry_dsn =
 662 
 663 # Custom HTTP endpoint to send events captured by the Sentry agent to. Default will log the events to stdout.
 664 ;custom_endpoint = /log
 665 
 666 # Rate of events to be reported between 0 (none) and 1 (all), float
 667 ;sample_rate = 1.0
 668 
 669 # Requests per second limit enforced an extended period, for Grafana backend log ingestion endpoint (/log).
 670 ;log_endpoint_requests_per_second_limit = 3
 671 
 672 # Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log).
 673 ;log_endpoint_burst_limit = 15
 674 
 675 #################################### Usage Quotas ########################
 676 [quota]
 677 ; enabled = false
 678 
 679 #### set quotas to -1 to make unlimited. ####
 680 # limit number of users per Org.
 681 ; org_user = 10
 682 
 683 # limit number of dashboards per Org.
 684 ; org_dashboard = 100
 685 
 686 # limit number of data_sources per Org.
 687 ; org_data_source = 10
 688 
 689 # limit number of api_keys per Org.
 690 ; org_api_key = 10
 691 
 692 # limit number of alerts per Org.
 693 ;org_alert_rule = 100
 694 
 695 # limit number of orgs a user can create.
 696 ; user_org = 10
 697 
 698 # Global limit of users.
 699 ; global_user = -1
 700 
 701 # global limit of orgs.
 702 ; global_org = -1
 703 
 704 # global limit of dashboards
 705 ; global_dashboard = -1
 706 
 707 # global limit of api_keys
 708 ; global_api_key = -1
 709 
 710 # global limit on number of logged in users.
 711 ; global_session = -1
 712 
 713 # global limit of alerts
 714 ;global_alert_rule = -1
 715 
 716 #################################### Unified Alerting ####################
 717 [unified_alerting]
 718 #Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed.```
 719 ;enabled = true
 720 
 721 # Comma-separated list of organization IDs for which to disable unified alerting. Only supported if unified alerting is enabled.
 722 ;disabled_orgs =
 723 
 724 # Specify the frequency of polling for admin config changes.
 725 # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 726 ;admin_config_poll_interval = 60s
 727 
 728 # Specify the frequency of polling for Alertmanager config changes.
 729 # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 730 ;alertmanager_config_poll_interval = 60s
 731 
 732 # Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
 733 ;ha_listen_address = "0.0.0.0:9094"
 734 
 735 # Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
 736 ;ha_advertise_address = ""
 737 
 738 # Comma-separated list of initial instances (in a format of host:port) that will form the HA cluster. Configuring this setting will enable High Availability mode for alerting.
 739 ;ha_peers = ""
 740 
 741 # Time to wait for an instance to send a notification via the Alertmanager. In HA, each Grafana instance will
 742 # be assigned a position (e.g. 0, 1). We then multiply this position with the timeout to indicate how long should
 743 # each instance wait before sending the notification to take into account replication lag.
 744 # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 745 ;ha_peer_timeout = "15s"
 746 
 747 # The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated
 748 # across cluster more quickly at the expense of increased bandwidth usage.
 749 # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 750 ;ha_gossip_interval = "200ms"
 751 
 752 # The interval between gossip full state syncs. Setting this interval lower (more frequent) will increase convergence speeds
 753 # across larger clusters at the expense of increased bandwidth usage.
 754 # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 755 ;ha_push_pull_interval = "60s"
 756 
 757 # Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
 758 ;execute_alerts = true
 759 
 760 # Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
 761 # The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 762 ;evaluation_timeout = 30s
 763 
 764 # Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
 765 ;max_attempts = 3
 766 
 767 # Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value  or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
 768 # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
 769 ;min_interval = 10s
 770 
 771 #################################### Alerting ############################
 772 [alerting]
 773 # Disable legacy alerting engine & UI features
 774 ;enabled = false
 775 
 776 # Makes it possible to turn off alert execution but alerting UI is visible
 777 ;execute_alerts = true
 778 
 779 # Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
 780 ;error_or_timeout = alerting
 781 
 782 # Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
 783 ;nodata_or_nullvalues = no_data
 784 
 785 # Alert notifications can include images, but rendering many images at the same time can overload the server
 786 # This limit will protect the server from render overloading and make sure notifications are sent out quickly
 787 ;concurrent_render_limit = 5
 788 
 789 # Default setting for alert calculation timeout. Default value is 30
 790 ;evaluation_timeout_seconds = 30
 791 
 792 # Default setting for alert notification timeout. Default value is 30
 793 ;notification_timeout_seconds = 30
 794 
 795 # Default setting for max attempts to sending alert notifications. Default value is 3
 796 ;max_attempts = 3
 797 
 798 # Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
 799 ;min_interval_seconds = 1
 800 
 801 # Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
 802 # This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
 803 ;max_annotation_age =
 804 
 805 # Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
 806 ;max_annotations_to_keep =
 807 
 808 #################################### Annotations #########################
 809 [annotations]
 810 # Configures the batch size for the annotation clean-up job. This setting is used for dashboard, API, and alert annotations.
 811 ;cleanupjob_batchsize = 100
 812 
 813 [annotations.dashboard]
 814 # Dashboard annotations means that annotations are associated with the dashboard they are created on.
 815 
 816 # Configures how long dashboard annotations are stored. Default is 0, which keeps them forever.
 817 # This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
 818 ;max_age =
 819 
 820 # Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations.
 821 ;max_annotations_to_keep =
 822 
 823 [annotations.api]
 824 # API annotations means that the annotations have been created using the API without any
 825 # association with a dashboard.
 826 
 827 # Configures how long Grafana stores API annotations. Default is 0, which keeps them forever.
 828 # This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
 829 ;max_age =
 830 
 831 # Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations.
 832 ;max_annotations_to_keep =
 833 
 834 #################################### Explore #############################
 835 [explore]
 836 # Enable the Explore section
 837 ;enabled = true
 838 
 839 #################################### Internal Grafana Metrics ##########################
 840 # Metrics available at HTTP API Url /metrics
 841 [metrics]
 842 # Disable / Enable internal metrics
 843 ;enabled           = true
 844 # Graphite Publish interval
 845 ;interval_seconds  = 10
 846 # Disable total stats (stat_totals_*) metrics to be generated
 847 ;disable_total_stats = false
 848 
 849 #If both are set, basic auth will be required for the metrics endpoint.
 850 ; basic_auth_username =
 851 ; basic_auth_password =
 852 
 853 # Metrics environment info adds dimensions to the `grafana_environment_info` metric, which
 854 # can expose more information about the Grafana instance.
 855 [metrics.environment_info]
 856 #exampleLabel1 = exampleValue1
 857 #exampleLabel2 = exampleValue2
 858 
 859 # Send internal metrics to Graphite
 860 [metrics.graphite]
 861 # Enable by setting the address setting (ex localhost:2003)
 862 ;address =
 863 ;prefix = prod.grafana.%(instance_name)s.
 864 
 865 #################################### Grafana.com integration  ##########################
 866 # Url used to import dashboards directly from Grafana.com
 867 [grafana_com]
 868 ;url = https://grafana.com
 869 
 870 #################################### Distributed tracing ############
 871 [tracing.jaeger]
 872 # Enable by setting the address sending traces to jaeger (ex localhost:6831)
 873 ;address = localhost:6831
 874 # Tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
 875 ;always_included_tag = tag1:value1
 876 # Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
 877 ;sampler_type = const
 878 # jaeger samplerconfig param
 879 # for "const" sampler, 0 or 1 for always false/true respectively
 880 # for "probabilistic" sampler, a probability between 0 and 1
 881 # for "rateLimiting" sampler, the number of spans per second
 882 # for "remote" sampler, param is the same as for "probabilistic"
 883 # and indicates the initial sampling rate before the actual one
 884 # is received from the mothership
 885 ;sampler_param = 1
 886 # sampling_server_url is the URL of a sampling manager providing a sampling strategy.
 887 ;sampling_server_url =
 888 # Whether or not to use Zipkin propagation (x-b3- HTTP headers).
 889 ;zipkin_propagation = false
 890 # Setting this to true disables shared RPC spans.
 891 # Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
 892 ;disable_shared_zipkin_spans = false
 893 
 894 #################################### External image storage ##########################
 895 [external_image_storage]
 896 # Used for uploading images to public servers so they can be included in slack/email messages.
 897 # you can choose between (s3, webdav, gcs, azure_blob, local)
 898 ;provider =
 899 
 900 [external_image_storage.s3]
 901 ;endpoint =
 902 ;path_style_access =
 903 ;bucket =
 904 ;region =
 905 ;path =
 906 ;access_key =
 907 ;secret_key =
 908 
 909 [external_image_storage.webdav]
 910 ;url =
 911 ;public_url =
 912 ;username =
 913 ;password =
 914 
 915 [external_image_storage.gcs]
 916 ;key_file =
 917 ;bucket =
 918 ;path =
 919 
 920 [external_image_storage.azure_blob]
 921 ;account_name =
 922 ;account_key =
 923 ;container_name =
 924 
 925 [external_image_storage.local]
 926 # does not require any configuration
 927 
 928 [rendering]
 929 # Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
 930 # URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
 931 ;server_url =
 932 # If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
 933 ;callback_url =
 934 # Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
 935 # which this setting can help protect against by only allowing a certain amount of concurrent requests.
 936 ;concurrent_render_request_limit = 30
 937 
 938 [panels]
 939 # If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
 940 ;disable_sanitize_html = false
 941 
 942 [plugins]
 943 ;enable_alpha = false
 944 ;app_tls_skip_verify_insecure = false
 945 # Enter a comma-separated list of plugin identifiers to identify plugins to load even if they are unsigned. Plugins with modified signatures are never loaded.
 946 ;allow_loading_unsigned_plugins =
 947 # Enable or disable installing / uninstalling / updating plugins directly from within Grafana.
 948 ;plugin_admin_enabled = false
 949 ;plugin_admin_external_manage_enabled = false
 950 ;plugin_catalog_url = https://grafana.com/grafana/plugins/
 951 # Enter a comma-separated list of plugin identifiers to hide in the plugin catalog.
 952 ;plugin_catalog_hidden_plugins =
 953 
 954 #################################### Grafana Live ##########################################
 955 [live]
 956 # max_connections to Grafana Live WebSocket endpoint per Grafana server instance. See Grafana Live docs
 957 # if you are planning to make it higher than default 100 since this can require some OS and infrastructure
 958 # tuning. 0 disables Live, -1 means unlimited connections.
 959 ;max_connections = 100
 960 
 961 # allowed_origins is a comma-separated list of origins that can establish connection with Grafana Live.
 962 # If not set then origin will be matched over root_url. Supports wildcard symbol "*".
 963 ;allowed_origins =
 964 
 965 # engine defines an HA (high availability) engine to use for Grafana Live. By default no engine used - in
 966 # this case Live features work only on a single Grafana server. Available options: "redis".
 967 # Setting ha_engine is an EXPERIMENTAL feature.
 968 ;ha_engine =
 969 
 970 # ha_engine_address sets a connection address for Live HA engine. Depending on engine type address format can differ.
 971 # For now we only support Redis connection address in "host:port" format.
 972 # This option is EXPERIMENTAL.
 973 ;ha_engine_address = "127.0.0.1:6379"
 974 
 975 #################################### Grafana Image Renderer Plugin ##########################
 976 [plugin.grafana-image-renderer]
 977 # Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
 978 # See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
 979 # timezone IDs. Fallbacks to TZ environment variable if not set.
 980 ;rendering_timezone =
 981 
 982 # Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
 983 # Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
 984 ;rendering_language =
 985 
 986 # Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
 987 # Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
 988 ;rendering_viewport_device_scale_factor =
 989 
 990 # Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
 991 # the security risk it's not recommended to ignore HTTPS errors.
 992 ;rendering_ignore_https_errors =
 993 
 994 # Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
 995 # only capture and log error messages. When enabled, debug messages are captured and logged as well.
 996 # For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
 997 # [log].filter = rendering:debug.
 998 ;rendering_verbose_logging =
 999 
1000 # Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
1001 # Default is false. This can be useful to enable (true) when troubleshooting.
1002 ;rendering_dumpio =
1003 
1004 # Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
1005 # here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
1006 ;rendering_args =
1007 
1008 # You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
1009 # Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
1010 # compatible with the plugin.
1011 ;rendering_chrome_bin =
1012 
1013 # Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
1014 # Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
1015 # Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
1016 ;rendering_mode =
1017 
1018 # When rendering_mode = clustered, you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
1019 # and will cluster using browser instances.
1020 # Mode 'context' will cluster using incognito pages.
1021 ;rendering_clustering_mode =
1022 # When rendering_mode = clustered, you can define the maximum number of browser instances/incognito pages that can execute concurrently. Default is '5'.
1023 ;rendering_clustering_max_concurrency =
1024 # When rendering_mode = clustered, you can specify the duration a rendering request can take before it will time out. Default is `30` seconds.
1025 ;rendering_clustering_timeout =
1026 
1027 # Limit the maximum viewport width, height and device scale factor that can be requested.
1028 ;rendering_viewport_max_width =
1029 ;rendering_viewport_max_height =
1030 ;rendering_viewport_max_device_scale_factor =
1031 
1032 # Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
1033 # a port not in use.
1034 ;grpc_host =
1035 ;grpc_port =
1036 
1037 [enterprise]
1038 # Path to a valid Grafana Enterprise license.jwt file
1039 ;license_path =
1040 
1041 [feature_toggles]
1042 # enable features, separated by spaces
1043 ;enable =
1044 
1045 [date_formats]
1046 # For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/
1047 
1048 # Default system date format used in time range picker and other places where full time is displayed
1049 ;full_date = YYYY-MM-DD HH:mm:ss
1050 
1051 # Used by graph and other places where we only show small intervals
1052 ;interval_second = HH:mm:ss
1053 ;interval_minute = HH:mm
1054 ;interval_hour = MM/DD HH:mm
1055 ;interval_day = MM/DD
1056 ;interval_month = YYYY-MM
1057 ;interval_year = YYYY
1058 
1059 # Experimental feature
1060 ;use_browser_locale = false
1061 
1062 # Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc.
1063 ;default_timezone = browser
1064 
1065 [expressions]
1066 # Enable or disable the expressions functionality.
1067 ;enabled = true
1068 
1069 [geomap]
1070 # Set the JSON configuration for the default basemap
1071 ;default_baselayer_config = `{
1072 ;  "type": "xyz",
1073 ;  "config": {
1074 ;    "attribution": "Open street map",
1075 ;    "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
1076 ;  }
1077 ;}`
1078 
1079 # Enable or disable loading other base map layers
1080 ;enable_custom_baselayers = true
View Code

3,安裝 jaeger

使用 OpenTelemetry 的 .NET 可觀測性
1 docker run -d --name jaeger -p 4317:4317 -p 4318:4318 -p 5775:5775/udp  -p 5778:5778 -p 6831:6831/udp -p 6832:6832/udp  -p 9411:9411 -p 14250:14250  -p 14268:14268  -p 14269:14269 -p 16685:16685 -p 16686:16686 -p 16687:16687 jaegertracing/all-in-one:latest
2  14250:grpc埠  -p 14268 http埠
View Code

4,程式碼整合

(1)nuget包的引用:

使用 OpenTelemetry 的 .NET 可觀測性
1 <ItemGroup>
2    <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.5.0" />
3    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.5.0" />
4    <PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.5.0-rc.1" />
5    <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.5.0" />
6    <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.5.0-beta.1" />
7    <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.5.0-beta.1" />
8 </ItemGroup>
View Code

(2) program類實現

使用 OpenTelemetry 的 .NET 可觀測性
 1 using OpenTelemetry.Metrics;
 2 using OpenTelemetry.Resources;
 3 using OpenTelemetry.Trace;
 4 
 5 var builder = WebApplication.CreateBuilder(args);
 6 
 7 // Add services to the container.
 8 
 9 builder.Services.AddControllers();
10 builder.Services.AddHttpClient();
11 #region 配置 OpenTelemetry
12 var tracingOtlpEndpoint = builder.Configuration["OTLP_ENDPOINT_URL"];
13 var otel = builder.Services.AddOpenTelemetry();
14 
15 // Configure OpenTelemetry Resources with the application name
16 otel.ConfigureResource(resource => resource
17     .AddService(serviceName: builder.Environment.ApplicationName));
18 
19 // Add Metrics for ASP.NET Core and our custom metrics and export to Prometheus
20 otel.WithMetrics(metrics => metrics
21     // Metrics provider from OpenTelemetry
22     .AddAspNetCoreInstrumentation()
23     .AddMeter("監控Meter.Test")
24     // Metrics provides by ASP.NET Core in .NET 8
25     .AddMeter("Microsoft.AspNetCore.Hosting")
26     .AddMeter("Microsoft.AspNetCore.Server.Kestrel")
27     .AddPrometheusExporter());
28 
29 // Add Tracing for ASP.NET Core and our custom ActivitySource and export to Jaeger
30 otel.WithTracing(tracing =>
31 {
32     tracing.AddAspNetCoreInstrumentation();
33     tracing.AddHttpClientInstrumentation();
34     tracing.AddSource("監控Activity.Test");
35     if (tracingOtlpEndpoint != null)
36     {
37         tracing.AddOtlpExporter(otlpOptions =>
38         {
39             otlpOptions.Endpoint = new Uri(tracingOtlpEndpoint);
40         });
41     }
42     else
43     {
44         tracing.AddConsoleExporter();
45     }
46 });
47 #endregion
48 var app = builder.Build();
49 
50 // Configure the HTTP request pipeline.
51 
52 app.UseHttpsRedirection();
53 
54 app.UseAuthorization();
55 
56 app.MapControllers();
57 // Configure the Prometheus scraping endpoint
58 app.MapPrometheusScrapingEndpoint();
59 app.Run();
View Code

(3)test API類實現

使用 OpenTelemetry 的 .NET 可觀測性
 1 [Route("api/[controller]")]
 2 [ApiController]
 3 public class TestController : ControllerBase
 4 {
 5   private readonly  ILogger<TestController> _logger;
 6     private readonly IHttpClientFactory _clientFactory;
 7     private readonly Meter _greeterMeter;
 8     private readonly ActivitySource _greeterActivitySource;
 9     public TestController(ILogger<TestController> logger, IHttpClientFactory clientFactory)
10     {
11         _clientFactory = clientFactory;
12         _logger = logger;
13         #region  OpenTelemetry 監控
14         // Custom metrics for the application
15         _greeterMeter = new Meter("監控Meter.Test", "1.0.0");
16         // Custom ActivitySource for the application
17         _greeterActivitySource = new ActivitySource("監控Activity.Test");
18         #endregion
19     }
20     [HttpGet("version")]
21     public string Version()
22     {
23         string hostName = Dns.GetHostName();
24         IPHostEntry hostEntry = Dns.GetHostEntry(hostName);
25         IPAddress[] addresses = hostEntry.AddressList;
26         string ip = string.Empty;
27         foreach (IPAddress address in addresses)
28         {
29             if (address.AddressFamily == AddressFamily.InterNetwork)
30             {
31                 ip = ip + "," + address.ToString();
32             }
33         }
34         int[] arr = { 1, 2, 3, 4, 5 };
35         foreach (ref int v in arr.AsSpan())
36         { v++; }
37         var ss = string.Join(",", arr);
38 
39         return "version:v7 " + ";IP:" + ip + "。時間:" + DateTime.Now;
40     }
41     [HttpGet("count")]
42     public async Task<String> SendGreeting()
43     {
44         var countGreetings = _greeterMeter.CreateCounter<int>("greetings.count", description: "Counts the number of greetings");
45         // Create a new Activity scoped to the method
46         using var activity = _greeterActivitySource.StartActivity("GreeterActivity");
47 
48         // Log a message
49         _logger.LogInformation("Sending greeting 日誌");
50 
51         // Increment the custom counter
52         countGreetings.Add(1);
53 
54         // Add a tag to the Activity
55         activity?.SetTag("greeting", "Hello World!");
56 
57         return "Hello World!" + DateTime.Now;
58     }
59     [HttpGet("NestedGreeting")]
60     public async Task SendNestedGreeting(int nestlevel)
61     {
62         // Create a new Activity scoped to the method
63         using var activity = _greeterActivitySource.StartActivity("GreeterActivity");
64 
65         if (nestlevel <= 5)
66         {
67             // Log a message
68             _logger.LogInformation("Sending greeting, level {nestlevel}", nestlevel);
69 
70             var countGreetings = _greeterMeter.CreateCounter<int>("greetings.count", description: "Counts the number of greetings");
71             // Increment the custom counter
72             countGreetings.Add(1);
73 
74             // Add a tag to the Activity
75             activity?.SetTag("nest-level", nestlevel);
76 
77             await HttpContext.Response.WriteAsync($"Nested Greeting, level: {nestlevel}\r\n");
78 
79             if (nestlevel > 0)
80             {
81                 var request = HttpContext.Request;
82                 var url = new Uri($"{request.Scheme}://{request.Host}{request.Path}?nestlevel={nestlevel - 1}");
83 
84                 // Makes an http call passing the activity information as http headers
85                 var nestedResult = await _clientFactory.CreateClient().GetStringAsync(url);
86                 await HttpContext.Response.WriteAsync(nestedResult);
87             }
88         }
89         else
90         {
91             // Log a message
92             _logger.LogError("Greeting nest level {nestlevel} too high", nestlevel);
93             await HttpContext.Response.WriteAsync("Nest level too high, max is 5");
94         }
95     }
96 }
View Code

相關文章