Skip to content

minefuto/junos-exporter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

junos-exporter

PyPI - Python Version PyPI GitHub

Overview

This is a prometheus exporter for Junos devices using PyEZ Tables and Views.
PyEZ Tables and Views allows you to extract operational information from Junos devices and map it to python objects using simple YAML definitions.
junos-exporter can convert the python objects created with PyEZ into prometheus metrics.
As a result, this exporter allows you to flexibly configure the metrics to be scraped using only YAML definitions.

The following configuration is required for Junos devices because PyEZ using netconf over ssh.

set system service netconf ssh

Installation

pip install junos-exporter

Usage

Docker(Recommended)
  1. Download config.yml:

    curl -sO https://raw.githubusercontent.com/minefuto/junos-exporter/refs/heads/main/config.yml
  2. Edit config.yml:

    general:
      prefix: junos  # Prefix for the metrics
      timeout: 60    # Request timeout for the exporter
    
    credentials:
      default:
        username: admin  # Junos device's username
        password: admin@123  # Junos device's password
  3. Update prometheus configuration:

    scrape_configs:
      - job_name: "junos-exporter"
        static_configs:
          - targets:
              - "192.168.1.1"  # Target device
        relabel_configs:
          - source_labels: [__address__]
            target_label: __param_target
          - source_labels: [__param_target]
            target_label: instance
          - target_label: __address__
            replacement: 127.0.0.1:9326
  4. Run the exporter using Docker:

    docker run -v config.yml:/app/config.yml ghcr.io/minefuto/junos-exporter
Pip
  1. Download config.yml:

    curl -s -o ~/.junos-exporter/config.yml --create-dirs https://raw.githubusercontent.com/minefuto/junos-exporter/refs/heads/main/config.yml
  2. Edit config.yml:

    general:
      prefix: junos  # Prefix for the metrics
      timeout: 60    # Request timeout for the exporter
    
    credentials:
      default:
        username: admin  # Junos device's username
        password: admin@123  # Junos device's password
  3. Update prometheus configuration:

    scrape_configs:
      - job_name: "junos-exporter"
        static_configs:
          - targets:
              - "192.168.1.1"  # Target device
        relabel_configs:
          - source_labels: [__address__]
            target_label: __param_target
          - source_labels: [__param_target]
            target_label: instance
          - target_label: __address__
            replacement: 127.0.0.1:9326
  4. Run the exporter:

    junos-exporter

Options

junos-exporter has several uvicorn options:

usage: junos-exporter [-h] [--host HOST] [--log-level {critical,error,warning,info,debug,trace}]
                      [--no-access-log] [--port PORT] [--reload] [--root-path ROOT_PATH] [--workers WORKERS]

options:
  -h, --help            Show this help message and exit
  --host HOST           Listen address [default: 0.0.0.0]
  --log-level           Log level [default: info]
  --no-access-log       Disable access log
  --port PORT           Listen port [default: 9326]
  --reload              Enable auto reload
  --root-path ROOT_PATH 
                        Root path [default: ""]
  --workers WORKERS     Number of worker processes [default: 1]

Credentials

This exporter allows you configure the authentication method per Junos device.
Add the module_name defined in the credentials section of config.yml to the query parameter when scraping.
e.g. http://localhost:9326/metrics?credential=vjunos&target=192.168.10.12 By setting __params_credential to vjunos in the prometheus configuration, vjunos credential will be used.

If credential is not specified as a query parameter, predefined credential(default) is used when scraping.

credentials:
  vjunos: # password authentication
    username: admin
    password: admin@123

  vjunos_key: # public key authentication
    username: admin
    private_key: ~/.ssh/id_rsa
    private_key_passphrase: admin@123 # option
scrape_configs:
  - job_name: "junos-exporter"
    static_configs:
      - targets:
          - "192.168.1.1"  # Target device using default credential
      - targets:
          - "192.168.1.2"  # Target device using "vjunos" credential
        labels:
          __params_credential: "vjunos"
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 127.0.0.1:9326

Metrics

This exporter allows you configure the metrics to be scraped per Junos device.
Add the module_name defined in the modules section of config.yml to the query parameter when scraping.
e.g. http://localhost:9326/metrics?module=router&target=192.168.10.12 By setting __params_module to router in the prometheus configuration, router module will be used.

If module is not specified as a query parameter, predefined module(default) is used when scraping.

Predefined Metrics

A module named default is predefined, providing metrics such as:

  • alarm information from show system alarm/show chassis alarm
  • fpc status and cpu/memory utilization from show chassis fpc
  • module information/status from show chassis hardware/show chassis environment
  • routing engine status and cpu/memory utilization from show chassis routing-engine
  • storage utilization from show system storage
  • interface status/error/drop/statistics from show interface extensive
  • interface tx/rx power from show interface diatnostics optics
  • lldp status from show lldp neighbor
  • lacp status from show lacp interface
  • route count from show route summary
  • arp information from show arp expiration-time
  • ospf status/cost from show ospf neighbor extensive/show ospf interface
  • bgp status/prefix count from show bgp summary
  • vrrp status from show vrrp
  • bfd status from show bfd session

Custom Metrics

You can extract python objects from any command on Junos device and convert it into prometheus metrics by defining YAML configurations.
Here is an example to create custom metrics using the show interface extensive command output.

  1. Define PyEZ Tables and Views

    Place the YAML file for PyEZ Tables and Views in the following directories:

    • PyEZ structured & unstructured tables and views configuration files:
      • Docker: /app/op/
      • Pip: ~/.junos-exporter/op/
    • TextFSM template files:
      • Docker: /app/textfsm/
      • Pip: ~/.junos-exporter/textfsm/

    Below is the mapping information from the show interface extensive command to python objects:

    PhysicalInterfaceStatus:
      rpc: get-interface-information
      args:
        extensive: True
        interface_name: '[afgxe][et]-*'
      key: name
      item: physical-interface
      view: PhysicalInterfaceStatusView
    
    PhysicalInterfaceStatusView:
      groups:
        traffic_statistics: traffic-statistics
        input_error_list: input-error-list
        output_error_list: output-error-list
        ethernet_pcs_statistics: ethernet-pcs-statistics
      fields:
        oper_status: oper-status
        admin_status: admin-status
        description: description
        speed: speed
        mtu: mtu
        link_mode: link-mode
        interface_flapped: interface-flapped
      fields_traffic_statistics:
        input_bytes: input-bytes
        input_packets: input-packets
        output_bytes: output-bytes
        output_packets: output-packets
      fields_input_error_list:
        input_errors: input-errors
        input_drops: input-drops
        framing_errors: framing-errors
        input_runts: input-runts
        input_discards: input-discards
        input_l3_incompletes: input-l3-incompletes
        input_l2_channel_errors: input-l2-channel-errors
        input_l2_mismatch_timeouts: input-l2-mismatch-timeouts
        input_fifo_errors: input-fifo-errors
        input_resource_errors: input-resource-errors
      fields_output_error_list:
        carrier_transitions: carrier-transitions
        output_errors: output-errors
        output_drops: output-drops
        collisions: output-collisions
        aged_packets: aged-packets
        mtu_errors: mtu-errors
        hs_link_crc_errors: hs-link-crc-errors
        output_fifo_errors: output-fifo-errors
        output_resource_errors: output-resource-errors
      fields_ethernet_pcs_statistics:
        bit_error_seconds: bit-error-seconds
        errored_blocks_seconds: errored-blocks-seconds

    Refer to Juniper's documentation for more details:

    Currently unsupported features:

    • Parsing unstructured output for Target FPC
    • Nested table definitions, such as PyEZ LacpPortTable
  2. Map python objects to metrics

    Edit the optables section in config.yml:

    optables:
      PhysicalInterfaceStatus:  # PyEZ table name
        metrics:
          - name: interface_speed  # Metric name
            value: speed           # Metric value
            type: gauge            # Metric type (gauge, count, or untyped)
            help: Speed of show interfaces extensive  # Metric description
            value_transform:       # (Optional) Transform string values into floats
              100mbps: 100000000
              1000mbps: 1000000000
              1Gbps: 1000000000
              10Gbps: 10000000000
              100Gbps: 100000000000
              _: 0  # (Optional) Fallback value for unknown strings (default: NaN)
          - name: interface_lastflap_seconds
            value: interface_flapped
            type: counter
            help: Last flapped of show interfaces extensive
            to_unixtime: True  # Convert timestamps to Unix time
        labels:
          - name: interface  # (Optional) Label name
            value: name      # Label value
          - name: description
            value: description

    With the above configuration, the following metrics can be scraped:

    # HELP junos_interface_speed Speed of show interfaces extensive
    # TYPE junos_interface_speed gauge
    junos_interface_speed{interface="ge-0/0/0",description="description example"} 1000000000.0
    
    # HELP junos_interface_lastflap_seconds_total Last flapped of show interfaces extensive
    # TYPE junos_interface_lastflap_seconds_total counter
    junos_interface_lastflap_seconds_total{interface="ge-0/0/0",description="description example"} 1745734677000.0
    

    Additional Notes:

    • PyEZ Table key are automatically mapped to key and name and can be used in metrics value or label value.

      • op/tables.yml
        RoutingEngineStatus:
          rpc: get-route-engine-information
          item: route-engine
          key: slot  <- !!
          view: RoutingEngineStatusView
      • config.yml
          RoutingEngineStatus:
            metrics:
            -snip-
            labels:
              - name: slot
                value: key
    • If there are multiple keys, they will be assigned as key.0, key.1, etc.

      • op/tables.yml
      LldpStatus:
        rpc: get-lldp-neighbors-information
        item: lldp-neighbor-information
        key:
          - lldp-local-port-id   # key.0, name.0
          - lldp-remote-port-id  # key.1, name.1
        view: LldpStatusView
      • config.yml
      LldpStatus:
        metrics:
          - name: lldp_neighbor_info
            value: 1
            type: gauge
            help: Information of show lldp neighbor
        labels:
          - name: remote
            value: remote_system_name
          - name: interface
            value: key.0
          - name: remote_interface
            value: key.1
    • You can assign fixed values for the metric:

      • config.yml
        HardwareStatus:
          metrics:
            - name: hardware_info
              value: 1  <- !!
              type: gauge
              help: Information of show chassis hardware
  3. Create a Module

    Add the table name to the modules section in config.yml:

    modules:
      router:
        tables:
          - PhysicalInterfaceStatus

    Update prometheus configuration to use the new module:

    scrape_configs:
      - job_name: "junos-exporter"
        static_configs:
          - targets:
              - "192.168.1.1"  # Target device
              - "192.168.1.2"
            labels:
              __params_module: "router"
        relabel_configs:
          - source_labels: [__address__]
            target_label: __param_target
          - source_labels: [__param_target]
            target_label: instance
          - target_label: __address__
            replacement: 127.0.0.1:9326

License

MIT

About

Prometheus Exporter for Junos using PyEZ Tables and Views

Topics

Resources

License

Stars

Watchers

Forks

Packages