1{ config, pkgs, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.services.prometheus; 7 8 workingDir = "/var/lib/" + cfg.stateDir; 9 10 # a wrapper that verifies that the configuration is valid 11 promtoolCheck = what: name: file: 12 if cfg.checkConfig then 13 pkgs.runCommandNoCCLocal 14 "${name}-${replaceStrings [" "] [""] what}-checked" 15 { buildInputs = [ cfg.package ]; } '' 16 ln -s ${file} $out 17 promtool ${what} $out 18 '' else file; 19 20 # Pretty-print JSON to a file 21 writePrettyJSON = name: x: 22 pkgs.runCommandNoCCLocal name {} '' 23 echo '${builtins.toJSON x}' | ${pkgs.jq}/bin/jq . > $out 24 ''; 25 26 generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig; 27 28 # This becomes the main config file for Prometheus 29 promConfig = { 30 global = filterValidPrometheus cfg.globalConfig; 31 rule_files = map (promtoolCheck "check rules" "rules") (cfg.ruleFiles ++ [ 32 (pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg.rules)) 33 ]); 34 scrape_configs = filterValidPrometheus cfg.scrapeConfigs; 35 remote_write = filterValidPrometheus cfg.remoteWrite; 36 remote_read = filterValidPrometheus cfg.remoteRead; 37 alerting = { 38 inherit (cfg) alertmanagers; 39 }; 40 }; 41 42 prometheusYml = let 43 yml = if cfg.configText != null then 44 pkgs.writeText "prometheus.yml" cfg.configText 45 else generatedPrometheusYml; 46 in promtoolCheck "check config" "prometheus.yml" yml; 47 48 cmdlineArgs = cfg.extraFlags ++ [ 49 "--storage.tsdb.path=${workingDir}/data/" 50 "--config.file=/run/prometheus/prometheus-substituted.yaml" 51 "--web.listen-address=${cfg.listenAddress}:${builtins.toString cfg.port}" 52 "--alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}" 53 "--alertmanager.timeout=${toString cfg.alertmanagerTimeout}s" 54 ] ++ optional (cfg.webExternalUrl != null) "--web.external-url=${cfg.webExternalUrl}" 55 ++ optional (cfg.retentionTime != null) "--storage.tsdb.retention.time=${cfg.retentionTime}"; 56 57 filterValidPrometheus = filterAttrsListRecursive (n: v: !(n == "_module" || v == null)); 58 filterAttrsListRecursive = pred: x: 59 if isAttrs x then 60 listToAttrs ( 61 concatMap (name: 62 let v = x.${name}; in 63 if pred name v then [ 64 (nameValuePair name (filterAttrsListRecursive pred v)) 65 ] else [] 66 ) (attrNames x) 67 ) 68 else if isList x then 69 map (filterAttrsListRecursive pred) x 70 else x; 71 72 mkDefOpt = type : defaultStr : description : mkOpt type (description + '' 73 74 Defaults to <literal>${defaultStr}</literal> in prometheus 75 when set to <literal>null</literal>. 76 ''); 77 78 mkOpt = type : description : mkOption { 79 type = types.nullOr type; 80 default = null; 81 inherit description; 82 }; 83 84 promTypes.globalConfig = types.submodule { 85 options = { 86 scrape_interval = mkDefOpt types.str "1m" '' 87 How frequently to scrape targets by default. 88 ''; 89 90 scrape_timeout = mkDefOpt types.str "10s" '' 91 How long until a scrape request times out. 92 ''; 93 94 evaluation_interval = mkDefOpt types.str "1m" '' 95 How frequently to evaluate rules by default. 96 ''; 97 98 external_labels = mkOpt (types.attrsOf types.str) '' 99 The labels to add to any time series or alerts when 100 communicating with external systems (federation, remote 101 storage, Alertmanager). 102 ''; 103 }; 104 }; 105 106 promTypes.remote_read = types.submodule { 107 options = { 108 url = mkOption { 109 type = types.str; 110 description = '' 111 ServerName extension to indicate the name of the server. 112 http://tools.ietf.org/html/rfc4366#section-3.1 113 ''; 114 }; 115 name = mkOpt types.str '' 116 Name of the remote read config, which if specified must be unique among remote read configs. 117 The name will be used in metrics and logging in place of a generated value to help users distinguish between 118 remote read configs. 119 ''; 120 required_matchers = mkOpt (types.attrsOf types.str) '' 121 An optional list of equality matchers which have to be 122 present in a selector to query the remote read endpoint. 123 ''; 124 remote_timeout = mkOpt types.str '' 125 Timeout for requests to the remote read endpoint. 126 ''; 127 read_recent = mkOpt types.bool '' 128 Whether reads should be made for queries for time ranges that 129 the local storage should have complete data for. 130 ''; 131 basic_auth = mkOpt (types.submodule { 132 options = { 133 username = mkOption { 134 type = types.str; 135 description = '' 136 HTTP username 137 ''; 138 }; 139 password = mkOpt types.str "HTTP password"; 140 password_file = mkOpt types.str "HTTP password file"; 141 }; 142 }) '' 143 Sets the `Authorization` header on every remote read request with the 144 configured username and password. 145 password and password_file are mutually exclusive. 146 ''; 147 bearer_token = mkOpt types.str '' 148 Sets the `Authorization` header on every remote read request with 149 the configured bearer token. It is mutually exclusive with `bearer_token_file`. 150 ''; 151 bearer_token_file = mkOpt types.str '' 152 Sets the `Authorization` header on every remote read request with the bearer token 153 read from the configured file. It is mutually exclusive with `bearer_token`. 154 ''; 155 tls_config = mkOpt promTypes.tls_config '' 156 Configures the remote read request's TLS settings. 157 ''; 158 proxy_url = mkOpt types.str "Optional Proxy URL."; 159 }; 160 }; 161 162 promTypes.remote_write = types.submodule { 163 options = { 164 url = mkOption { 165 type = types.str; 166 description = '' 167 ServerName extension to indicate the name of the server. 168 http://tools.ietf.org/html/rfc4366#section-3.1 169 ''; 170 }; 171 remote_timeout = mkOpt types.str '' 172 Timeout for requests to the remote write endpoint. 173 ''; 174 write_relabel_configs = mkOpt (types.listOf promTypes.relabel_config) '' 175 List of remote write relabel configurations. 176 ''; 177 name = mkOpt types.str '' 178 Name of the remote write config, which if specified must be unique among remote write configs. 179 The name will be used in metrics and logging in place of a generated value to help users distinguish between 180 remote write configs. 181 ''; 182 basic_auth = mkOpt (types.submodule { 183 options = { 184 username = mkOption { 185 type = types.str; 186 description = '' 187 HTTP username 188 ''; 189 }; 190 password = mkOpt types.str "HTTP password"; 191 password_file = mkOpt types.str "HTTP password file"; 192 }; 193 }) '' 194 Sets the `Authorization` header on every remote write request with the 195 configured username and password. 196 password and password_file are mutually exclusive. 197 ''; 198 bearer_token = mkOpt types.str '' 199 Sets the `Authorization` header on every remote write request with 200 the configured bearer token. It is mutually exclusive with `bearer_token_file`. 201 ''; 202 bearer_token_file = mkOpt types.str '' 203 Sets the `Authorization` header on every remote write request with the bearer token 204 read from the configured file. It is mutually exclusive with `bearer_token`. 205 ''; 206 tls_config = mkOpt promTypes.tls_config '' 207 Configures the remote write request's TLS settings. 208 ''; 209 proxy_url = mkOpt types.str "Optional Proxy URL."; 210 queue_config = mkOpt (types.submodule { 211 options = { 212 capacity = mkOpt types.int '' 213 Number of samples to buffer per shard before we block reading of more 214 samples from the WAL. It is recommended to have enough capacity in each 215 shard to buffer several requests to keep throughput up while processing 216 occasional slow remote requests. 217 ''; 218 max_shards = mkOpt types.int '' 219 Maximum number of shards, i.e. amount of concurrency. 220 ''; 221 min_shards = mkOpt types.int '' 222 Minimum number of shards, i.e. amount of concurrency. 223 ''; 224 max_samples_per_send = mkOpt types.int '' 225 Maximum number of samples per send. 226 ''; 227 batch_send_deadline = mkOpt types.str '' 228 Maximum time a sample will wait in buffer. 229 ''; 230 min_backoff = mkOpt types.str '' 231 Initial retry delay. Gets doubled for every retry. 232 ''; 233 max_backoff = mkOpt types.str '' 234 Maximum retry delay. 235 ''; 236 }; 237 }) '' 238 Configures the queue used to write to remote storage. 239 ''; 240 metadata_config = mkOpt (types.submodule { 241 options = { 242 send = mkOpt types.bool '' 243 Whether metric metadata is sent to remote storage or not. 244 ''; 245 send_interval = mkOpt types.str '' 246 How frequently metric metadata is sent to remote storage. 247 ''; 248 }; 249 }) '' 250 Configures the sending of series metadata to remote storage. 251 Metadata configuration is subject to change at any point 252 or be removed in future releases. 253 ''; 254 }; 255 }; 256 257 promTypes.scrape_config = types.submodule { 258 options = { 259 job_name = mkOption { 260 type = types.str; 261 description = '' 262 The job name assigned to scraped metrics by default. 263 ''; 264 }; 265 scrape_interval = mkOpt types.str '' 266 How frequently to scrape targets from this job. Defaults to the 267 globally configured default. 268 ''; 269 270 scrape_timeout = mkOpt types.str '' 271 Per-target timeout when scraping this job. Defaults to the 272 globally configured default. 273 ''; 274 275 metrics_path = mkDefOpt types.str "/metrics" '' 276 The HTTP resource path on which to fetch metrics from targets. 277 ''; 278 279 honor_labels = mkDefOpt types.bool "false" '' 280 Controls how Prometheus handles conflicts between labels 281 that are already present in scraped data and labels that 282 Prometheus would attach server-side ("job" and "instance" 283 labels, manually configured target labels, and labels 284 generated by service discovery implementations). 285 286 If honor_labels is set to "true", label conflicts are 287 resolved by keeping label values from the scraped data and 288 ignoring the conflicting server-side labels. 289 290 If honor_labels is set to "false", label conflicts are 291 resolved by renaming conflicting labels in the scraped data 292 to "exported_&lt;original-label&gt;" (for example 293 "exported_instance", "exported_job") and then attaching 294 server-side labels. This is useful for use cases such as 295 federation, where all labels specified in the target should 296 be preserved. 297 ''; 298 299 honor_timestamps = mkDefOpt types.bool "true" '' 300 honor_timestamps controls whether Prometheus respects the timestamps present 301 in scraped data. 302 303 If honor_timestamps is set to <literal>true</literal>, the timestamps of the metrics exposed 304 by the target will be used. 305 306 If honor_timestamps is set to <literal>false</literal>, the timestamps of the metrics exposed 307 by the target will be ignored. 308 ''; 309 310 scheme = mkDefOpt (types.enum ["http" "https"]) "http" '' 311 The URL scheme with which to fetch metrics from targets. 312 ''; 313 314 params = mkOpt (types.attrsOf (types.listOf types.str)) '' 315 Optional HTTP URL parameters. 316 ''; 317 318 basic_auth = mkOpt (types.submodule { 319 options = { 320 username = mkOption { 321 type = types.str; 322 description = '' 323 HTTP username 324 ''; 325 }; 326 password = mkOption { 327 type = types.str; 328 description = '' 329 HTTP password 330 ''; 331 }; 332 }; 333 }) '' 334 Optional http login credentials for metrics scraping. 335 ''; 336 337 bearer_token = mkOpt types.str '' 338 Sets the `Authorization` header on every scrape request with 339 the configured bearer token. It is mutually exclusive with 340 <option>bearer_token_file</option>. 341 ''; 342 343 bearer_token_file = mkOpt types.str '' 344 Sets the `Authorization` header on every scrape request with 345 the bearer token read from the configured file. It is mutually 346 exclusive with <option>bearer_token</option>. 347 ''; 348 349 tls_config = mkOpt promTypes.tls_config '' 350 Configures the scrape request's TLS settings. 351 ''; 352 353 proxy_url = mkOpt types.str '' 354 Optional proxy URL. 355 ''; 356 357 ec2_sd_configs = mkOpt (types.listOf promTypes.ec2_sd_config) '' 358 List of EC2 service discovery configurations. 359 ''; 360 361 dns_sd_configs = mkOpt (types.listOf promTypes.dns_sd_config) '' 362 List of DNS service discovery configurations. 363 ''; 364 365 consul_sd_configs = mkOpt (types.listOf promTypes.consul_sd_config) '' 366 List of Consul service discovery configurations. 367 ''; 368 369 file_sd_configs = mkOpt (types.listOf promTypes.file_sd_config) '' 370 List of file service discovery configurations. 371 ''; 372 373 gce_sd_configs = mkOpt (types.listOf promTypes.gce_sd_config) '' 374 List of Google Compute Engine service discovery configurations. 375 376 See <link 377 xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#gce_sd_config">the 378 relevant Prometheus configuration docs</link> for more detail. 379 ''; 380 381 static_configs = mkOpt (types.listOf promTypes.static_config) '' 382 List of labeled target groups for this job. 383 ''; 384 385 relabel_configs = mkOpt (types.listOf promTypes.relabel_config) '' 386 List of relabel configurations. 387 ''; 388 389 metric_relabel_configs = mkOpt (types.listOf promTypes.relabel_config) '' 390 List of metric relabel configurations. 391 ''; 392 393 sample_limit = mkDefOpt types.int "0" '' 394 Per-scrape limit on number of scraped samples that will be accepted. 395 If more than this number of samples are present after metric relabelling 396 the entire scrape will be treated as failed. 0 means no limit. 397 ''; 398 }; 399 }; 400 401 promTypes.static_config = types.submodule { 402 options = { 403 targets = mkOption { 404 type = types.listOf types.str; 405 description = '' 406 The targets specified by the target group. 407 ''; 408 }; 409 labels = mkOption { 410 type = types.attrsOf types.str; 411 default = {}; 412 description = '' 413 Labels assigned to all metrics scraped from the targets. 414 ''; 415 }; 416 }; 417 }; 418 419 promTypes.ec2_sd_config = types.submodule { 420 options = { 421 region = mkOption { 422 type = types.str; 423 description = '' 424 The AWS Region. 425 ''; 426 }; 427 endpoint = mkOpt types.str '' 428 Custom endpoint to be used. 429 ''; 430 431 access_key = mkOpt types.str '' 432 The AWS API key id. If blank, the environment variable 433 <literal>AWS_ACCESS_KEY_ID</literal> is used. 434 ''; 435 436 secret_key = mkOpt types.str '' 437 The AWS API key secret. If blank, the environment variable 438 <literal>AWS_SECRET_ACCESS_KEY</literal> is used. 439 ''; 440 441 profile = mkOpt types.str '' 442 Named AWS profile used to connect to the API. 443 ''; 444 445 role_arn = mkOpt types.str '' 446 AWS Role ARN, an alternative to using AWS API keys. 447 ''; 448 449 refresh_interval = mkDefOpt types.str "60s" '' 450 Refresh interval to re-read the instance list. 451 ''; 452 453 port = mkDefOpt types.int "80" '' 454 The port to scrape metrics from. If using the public IP 455 address, this must instead be specified in the relabeling 456 rule. 457 ''; 458 459 filters = mkOpt (types.listOf promTypes.filter) '' 460 Filters can be used optionally to filter the instance list by other criteria. 461 ''; 462 }; 463 }; 464 465 promTypes.filter = types.submodule { 466 options = { 467 name = mkOption { 468 type = types.str; 469 description = '' 470 See <link xlink:href="https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html">this list</link> 471 for the available filters. 472 ''; 473 }; 474 475 values = mkOption { 476 type = types.listOf types.str; 477 default = []; 478 description = '' 479 Value of the filter. 480 ''; 481 }; 482 }; 483 }; 484 485 promTypes.dns_sd_config = types.submodule { 486 options = { 487 names = mkOption { 488 type = types.listOf types.str; 489 description = '' 490 A list of DNS SRV record names to be queried. 491 ''; 492 }; 493 494 refresh_interval = mkDefOpt types.str "30s" '' 495 The time after which the provided names are refreshed. 496 ''; 497 }; 498 }; 499 500 promTypes.consul_sd_config = types.submodule { 501 options = { 502 server = mkDefOpt types.str "localhost:8500" '' 503 Consul server to query. 504 ''; 505 506 token = mkOpt types.str "Consul token"; 507 508 datacenter = mkOpt types.str "Consul datacenter"; 509 510 scheme = mkDefOpt types.str "http" "Consul scheme"; 511 512 username = mkOpt types.str "Consul username"; 513 514 password = mkOpt types.str "Consul password"; 515 516 tls_config = mkOpt promTypes.tls_config '' 517 Configures the Consul request's TLS settings. 518 ''; 519 520 services = mkOpt (types.listOf types.str) '' 521 A list of services for which targets are retrieved. 522 ''; 523 524 tags = mkOpt (types.listOf types.str) '' 525 An optional list of tags used to filter nodes for a given 526 service. Services must contain all tags in the list. 527 ''; 528 529 node_meta = mkOpt (types.attrsOf types.str) '' 530 Node metadata used to filter nodes for a given service. 531 ''; 532 533 tag_separator = mkDefOpt types.str "," '' 534 The string by which Consul tags are joined into the tag label. 535 ''; 536 537 allow_stale = mkOpt types.bool '' 538 Allow stale Consul results 539 (see <link xlink:href="https://www.consul.io/api/index.html#consistency-modes"/>). 540 541 Will reduce load on Consul. 542 ''; 543 544 refresh_interval = mkDefOpt types.str "30s" '' 545 The time after which the provided names are refreshed. 546 547 On large setup it might be a good idea to increase this value 548 because the catalog will change all the time. 549 ''; 550 }; 551 }; 552 553 promTypes.file_sd_config = types.submodule { 554 options = { 555 files = mkOption { 556 type = types.listOf types.str; 557 description = '' 558 Patterns for files from which target groups are extracted. Refer 559 to the Prometheus documentation for permitted filename patterns 560 and formats. 561 ''; 562 }; 563 564 refresh_interval = mkDefOpt types.str "5m" '' 565 Refresh interval to re-read the files. 566 ''; 567 }; 568 }; 569 570 promTypes.gce_sd_config = types.submodule { 571 options = { 572 # Use `mkOption` instead of `mkOpt` for project and zone because they are 573 # required configuration values for `gce_sd_config`. 574 project = mkOption { 575 type = types.str; 576 description = '' 577 The GCP Project. 578 ''; 579 }; 580 581 zone = mkOption { 582 type = types.str; 583 description = '' 584 The zone of the scrape targets. If you need multiple zones use multiple 585 gce_sd_configs. 586 ''; 587 }; 588 589 filter = mkOpt types.str '' 590 Filter can be used optionally to filter the instance list by other 591 criteria Syntax of this filter string is described here in the filter 592 query parameter section: <link 593 xlink:href="https://cloud.google.com/compute/docs/reference/latest/instances/list" 594 />. 595 ''; 596 597 refresh_interval = mkDefOpt types.str "60s" '' 598 Refresh interval to re-read the cloud instance list. 599 ''; 600 601 port = mkDefOpt types.port "80" '' 602 The port to scrape metrics from. If using the public IP address, this 603 must instead be specified in the relabeling rule. 604 ''; 605 606 tag_separator = mkDefOpt types.str "," '' 607 The tag separator used to separate concatenated GCE instance network tags. 608 609 See the GCP documentation on network tags for more information: <link 610 xlink:href="https://cloud.google.com/vpc/docs/add-remove-network-tags" 611 /> 612 ''; 613 }; 614 }; 615 616 promTypes.relabel_config = types.submodule { 617 options = { 618 source_labels = mkOpt (types.listOf types.str) '' 619 The source labels select values from existing labels. Their content 620 is concatenated using the configured separator and matched against 621 the configured regular expression. 622 ''; 623 624 separator = mkDefOpt types.str ";" '' 625 Separator placed between concatenated source label values. 626 ''; 627 628 target_label = mkOpt types.str '' 629 Label to which the resulting value is written in a replace action. 630 It is mandatory for replace actions. 631 ''; 632 633 regex = mkDefOpt types.str "(.*)" '' 634 Regular expression against which the extracted value is matched. 635 ''; 636 637 modulus = mkOpt types.int '' 638 Modulus to take of the hash of the source label values. 639 ''; 640 641 replacement = mkDefOpt types.str "$1" '' 642 Replacement value against which a regex replace is performed if the 643 regular expression matches. 644 ''; 645 646 action = 647 mkDefOpt (types.enum ["replace" "keep" "drop" "hashmod" "labelmap" "labeldrop" "labelkeep"]) "replace" '' 648 Action to perform based on regex matching. 649 ''; 650 }; 651 }; 652 653 promTypes.tls_config = types.submodule { 654 options = { 655 ca_file = mkOpt types.str '' 656 CA certificate to validate API server certificate with. 657 ''; 658 659 cert_file = mkOpt types.str '' 660 Certificate file for client cert authentication to the server. 661 ''; 662 663 key_file = mkOpt types.str '' 664 Key file for client cert authentication to the server. 665 ''; 666 667 server_name = mkOpt types.str '' 668 ServerName extension to indicate the name of the server. 669 http://tools.ietf.org/html/rfc4366#section-3.1 670 ''; 671 672 insecure_skip_verify = mkOpt types.bool '' 673 Disable validation of the server certificate. 674 ''; 675 }; 676 }; 677 678in { 679 680 imports = [ 681 (mkRenamedOptionModule [ "services" "prometheus2" ] [ "services" "prometheus" ]) 682 ]; 683 684 options.services.prometheus = { 685 686 enable = mkOption { 687 type = types.bool; 688 default = false; 689 description = '' 690 Enable the Prometheus monitoring daemon. 691 ''; 692 }; 693 694 package = mkOption { 695 type = types.package; 696 default = pkgs.prometheus; 697 defaultText = "pkgs.prometheus"; 698 description = '' 699 The prometheus package that should be used. 700 ''; 701 }; 702 703 port = mkOption { 704 type = types.port; 705 default = 9090; 706 description = '' 707 Port to listen on. 708 ''; 709 }; 710 711 listenAddress = mkOption { 712 type = types.str; 713 default = "0.0.0.0"; 714 description = '' 715 Address to listen on for the web interface, API, and telemetry. 716 ''; 717 }; 718 719 stateDir = mkOption { 720 type = types.str; 721 default = "prometheus2"; 722 description = '' 723 Directory below <literal>/var/lib</literal> to store Prometheus metrics data. 724 This directory will be created automatically using systemd's StateDirectory mechanism. 725 ''; 726 }; 727 728 extraFlags = mkOption { 729 type = types.listOf types.str; 730 default = []; 731 description = '' 732 Extra commandline options when launching Prometheus. 733 ''; 734 }; 735 736 environmentFile = mkOption { 737 type = types.nullOr types.path; 738 default = null; 739 example = "/root/prometheus.env"; 740 description = '' 741 Environment file as defined in <citerefentry> 742 <refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum> 743 </citerefentry>. 744 745 Secrets may be passed to the service without adding them to the 746 world-readable Nix store, by specifying placeholder variables as 747 the option value in Nix and setting these variables accordingly in the 748 environment file. 749 750 Environment variables from this file will be interpolated into the 751 config file using envsubst with this syntax: 752 <literal>$ENVIRONMENT ''${VARIABLE}</literal> 753 754 <programlisting> 755 # Example scrape config entry handling an OAuth bearer token 756 { 757 job_name = "home_assistant"; 758 metrics_path = "/api/prometheus"; 759 scheme = "https"; 760 bearer_token = "\''${HOME_ASSISTANT_BEARER_TOKEN}"; 761 [...] 762 } 763 </programlisting> 764 765 <programlisting> 766 # Content of the environment file 767 HOME_ASSISTANT_BEARER_TOKEN=someoauthbearertoken 768 </programlisting> 769 770 Note that this file needs to be available on the host on which 771 <literal>Prometheus</literal> is running. 772 ''; 773 }; 774 775 configText = mkOption { 776 type = types.nullOr types.lines; 777 default = null; 778 description = '' 779 If non-null, this option defines the text that is written to 780 prometheus.yml. If null, the contents of prometheus.yml is generated 781 from the structured config options. 782 ''; 783 }; 784 785 globalConfig = mkOption { 786 type = promTypes.globalConfig; 787 default = {}; 788 description = '' 789 Parameters that are valid in all configuration contexts. They 790 also serve as defaults for other configuration sections 791 ''; 792 }; 793 794 remoteRead = mkOption { 795 type = types.listOf promTypes.remote_read; 796 default = []; 797 description = '' 798 Parameters of the endpoints to query from. 799 See <link xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_read">the official documentation</link> for more information. 800 ''; 801 }; 802 803 remoteWrite = mkOption { 804 type = types.listOf promTypes.remote_write; 805 default = []; 806 description = '' 807 Parameters of the endpoints to send samples to. 808 See <link xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write">the official documentation</link> for more information. 809 ''; 810 }; 811 812 rules = mkOption { 813 type = types.listOf types.str; 814 default = []; 815 description = '' 816 Alerting and/or Recording rules to evaluate at runtime. 817 ''; 818 }; 819 820 ruleFiles = mkOption { 821 type = types.listOf types.path; 822 default = []; 823 description = '' 824 Any additional rules files to include in this configuration. 825 ''; 826 }; 827 828 scrapeConfigs = mkOption { 829 type = types.listOf promTypes.scrape_config; 830 default = []; 831 description = '' 832 A list of scrape configurations. 833 ''; 834 }; 835 836 alertmanagers = mkOption { 837 type = types.listOf types.attrs; 838 example = literalExample '' 839 [ { 840 scheme = "https"; 841 path_prefix = "/alertmanager"; 842 static_configs = [ { 843 targets = [ 844 "prometheus.domain.tld" 845 ]; 846 } ]; 847 } ] 848 ''; 849 default = []; 850 description = '' 851 A list of alertmanagers to send alerts to. 852 See <link xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config">the official documentation</link> for more information. 853 ''; 854 }; 855 856 alertmanagerNotificationQueueCapacity = mkOption { 857 type = types.int; 858 default = 10000; 859 description = '' 860 The capacity of the queue for pending alert manager notifications. 861 ''; 862 }; 863 864 alertmanagerTimeout = mkOption { 865 type = types.int; 866 default = 10; 867 description = '' 868 Alert manager HTTP API timeout (in seconds). 869 ''; 870 }; 871 872 webExternalUrl = mkOption { 873 type = types.nullOr types.str; 874 default = null; 875 example = "https://example.com/"; 876 description = '' 877 The URL under which Prometheus is externally reachable (for example, 878 if Prometheus is served via a reverse proxy). 879 ''; 880 }; 881 882 checkConfig = mkOption { 883 type = types.bool; 884 default = true; 885 description = '' 886 Check configuration with <literal>promtool 887 check</literal>. The call to <literal>promtool</literal> is 888 subject to sandboxing by Nix. When credentials are stored in 889 external files (<literal>password_file</literal>, 890 <literal>bearer_token_file</literal>, etc), they will not be 891 visible to <literal>promtool</literal> and it will report 892 errors, despite a correct configuration. 893 ''; 894 }; 895 896 retentionTime = mkOption { 897 type = types.nullOr types.str; 898 default = null; 899 example = "15d"; 900 description = '' 901 How long to retain samples in storage. 902 ''; 903 }; 904 }; 905 906 config = mkIf cfg.enable { 907 assertions = [ 908 ( let 909 # Match something with dots (an IPv4 address) or something ending in 910 # a square bracket (an IPv6 addresses) followed by a port number. 911 legacy = builtins.match "(.*\\..*|.*]):([[:digit:]]+)" cfg.listenAddress; 912 in { 913 assertion = legacy == null; 914 message = '' 915 Do not specify the port for Prometheus to listen on in the 916 listenAddress option; use the port option instead: 917 services.prometheus.listenAddress = ${builtins.elemAt legacy 0}; 918 services.prometheus.port = ${builtins.elemAt legacy 1}; 919 ''; 920 } 921 ) 922 ]; 923 924 users.groups.prometheus.gid = config.ids.gids.prometheus; 925 users.users.prometheus = { 926 description = "Prometheus daemon user"; 927 uid = config.ids.uids.prometheus; 928 group = "prometheus"; 929 }; 930 systemd.services.prometheus = { 931 wantedBy = [ "multi-user.target" ]; 932 after = [ "network.target" ]; 933 preStart = '' 934 ${lib.getBin pkgs.envsubst}/bin/envsubst -o "/run/prometheus/prometheus-substituted.yaml" \ 935 -i "${prometheusYml}" 936 ''; 937 serviceConfig = { 938 ExecStart = "${cfg.package}/bin/prometheus" + 939 optionalString (length cmdlineArgs != 0) (" \\\n " + 940 concatStringsSep " \\\n " cmdlineArgs); 941 User = "prometheus"; 942 Restart = "always"; 943 EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; 944 RuntimeDirectory = "prometheus"; 945 RuntimeDirectoryMode = "0700"; 946 WorkingDirectory = workingDir; 947 StateDirectory = cfg.stateDir; 948 }; 949 }; 950 }; 951}