### Install and Run with Python Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/getting-started.md Installs the Meraki Dashboard Exporter using uv pip, sets the API key environment variable, and starts the exporter. Requires Python 3.11+ and Meraki Dashboard API access. ```bash uv pip install meraki-dashboard-exporter export MERAKI_API_KEY=your_key python -m meraki_dashboard_exporter ``` -------------------------------- ### Quick Start: Run Meraki Exporter with Docker Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/README.md This snippet guides users through setting up and running the Meraki Dashboard Exporter using Docker. It involves copying an example environment file, setting the Meraki API key, and starting the service with Docker Compose. Metrics are then accessible at http://localhost:9099/metrics. ```bash cp .env.example .env # Edit .env and set: MERAKI_EXPORTER_MERAKI__API_KEY=your_api_key_here docker-compose up -d ``` -------------------------------- ### Quick Start: Install Meraki Exporter with Python Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/README.md This section details how to install the Meraki Dashboard Exporter directly using Python. It involves installing dependencies with uv pip, setting the Meraki API key as an environment variable, and then running the exporter module. ```bash uv pip install -e . export MERAKI_EXPORTER_MERAKI__API_KEY=your_api_key_here ``` -------------------------------- ### API Mock Configuration Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/tests/CLAUDE.md Provides examples for configuring the MockAPIBuilder. This includes basic setup with organizations and devices, adding custom API responses for specific endpoints, and simulating API errors. ```python # Basic mock setup mock_api_builder.with_organizations([org]).with_devices(devices) # Add specific API responses mock_api_builder.with_custom_response( "getOrganizationWirelessDevicesChannelUtilization", [{"serial": "Q2XX-XXXX-XXXX", "utilization": 45.2}] ) # Configure error scenarios mock_api_builder.with_error( "getOrganizationDevices", exception_type="ConnectionError" ) ``` -------------------------------- ### Environment Variable Examples (Bash) Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/config.md Demonstrates how to set environment variables for configuring the Meraki Dashboard Exporter. This includes examples for Meraki API configuration, logging levels, and general API settings. ```bash export MERAKI_EXPORTER_MERAKI__API_KEY=your_api_key_here export MERAKI_EXPORTER_MERAKI__ORG_ID=123456 export MERAKI_EXPORTER_LOGGING__LEVEL=INFO export MERAKI_EXPORTER_API__TIMEOUT=30 export MERAKI_EXPORTER_API__CONCURRENCY_LIMIT=5 ``` -------------------------------- ### Start with Docker Compose Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/CLAUDE.md Starts the project services, including the exporter, using Docker Compose. This command is used for containerized development and deployment. ```bash docker-compose up ``` -------------------------------- ### Start with Docker Compose Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/AGENTS.md Starts the project services, including the exporter, using Docker Compose. This command is used for containerized development and deployment. ```bash docker-compose up ``` -------------------------------- ### Start Meraki Dashboard Exporter Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/CLAUDE.md Starts the Meraki Dashboard Exporter application using the uvicorn server. This command is the primary way to run the exporter in development or production environments. ```bash uv run python -m meraki_dashboard_exporter ``` -------------------------------- ### Install GitHub CLI (Bash) Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/RELEASE.md Provides installation instructions for the GitHub CLI tool on macOS using Homebrew and a link to Linux installation documentation. ```bash # macOS brew install gh # Linux # See: https://github.com/cli/cli/blob/trunk/docs/install_linux.md ``` -------------------------------- ### Run Meraki Exporter in Python Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/README.md After installation and setting environment variables, this command executes the Meraki Dashboard Exporter Python module. It starts the exporter service, making Meraki metrics available for collection. ```bash python -m meraki_dashboard_exporter ``` -------------------------------- ### Start Meraki Dashboard Exporter Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/AGENTS.md Starts the Meraki Dashboard Exporter application using the uvicorn server. This command is the primary way to run the exporter in development or production environments. ```bash uv run python -m meraki_dashboard_exporter ``` -------------------------------- ### Verify Exporter Status Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/getting-started.md Checks the exporter's metrics endpoint and health status using curl. The metrics endpoint should return Prometheus-formatted metrics, and the health endpoint should return a JSON status object. ```bash curl http://localhost:9099/metrics curl http://localhost:9099/health ``` -------------------------------- ### Docker Compose Example for Meraki Exporter and OTEL Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/README.md This YAML configuration defines a Docker Compose setup for running the Meraki Dashboard Exporter alongside an OpenTelemetry collector. It specifies environment variables for API keys and OTEL integration, maps ports, and mounts the OTEL collector configuration file. ```yaml services: meraki-exporter: image: meraki-dashboard-exporter environment: - MERAKI_EXPORTER_MERAKI__API_KEY=${MERAKI_EXPORTER_MERAKI__API_KEY} - MERAKI_EXPORTER_OTEL__ENABLED=true - MERAKI_EXPORTER_OTEL__ENDPOINT=http://otel-collector:4317 ports: - "9099:9099" otel-collector: image: otel/opentelemetry-collector-contrib:latest command: ["--config=/etc/otel-collector-config.yaml"] volumes: - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml ports: - "4317:4317" # OTLP gRPC receiver ``` -------------------------------- ### Start Exporter with Docker Compose Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/deployment-operations.md This snippet shows the command to start the meraki-dashboard-exporter using Docker Compose. It assumes the user has configured their environment variables in a .env file. ```bash docker compose up -d ``` -------------------------------- ### Prometheus Query Examples for Meraki Metrics Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/metrics/index.md This snippet provides example Prometheus Query Language (PromQL) queries for monitoring Cisco Meraki infrastructure. These examples demonstrate how to retrieve device availability, client counts, and environmental sensor data, useful for building dashboards and alerts. ```promql # Device availability by organization avg by (org_name) (meraki_device_up) * 100 # Top networks by client count topk(5, sum by (network_name) (meraki_mr_clients_connected)) # Temperature sensors above threshold meraki_mt_temperature_celsius > 30 ``` -------------------------------- ### Enhanced Method Documentation Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/refactor-claude.txt Examples of enhanced documentation for complex methods and utilities. This includes detailed docstrings with usage examples for specific functions like `_set_packet_metric_value`, `ManagedTaskGroup`, and the `@register_collector` decorator, clarifying their purpose, parameters, and behavior. ```APIDOC Method: _set_packet_metric_value - **Description**: Sets the value for a packet-related metric, incorporating a caching strategy to optimize updates. Explains the caching mechanism, cache invalidation, and how values are aggregated. - **Parameters**: - `metric_name` (str): The name of the metric to update. - `value` (float): The new value for the metric. - `packet_id` (str): Identifier for the packet. - `cache_key` (str): Key used for caching the metric value. - **Returns**: None - **Example**: ```python # Assuming 'self' is an instance with caching capabilities self.cache.set(cache_key, value, ttl=300) self._set_packet_metric_value('packet_loss', 0.01, 'pkt_123', cache_key) ``` Utility: ManagedTaskGroup - **Description**: A context manager for managing groups of asynchronous tasks. Provides clear usage examples and guidance on when to use it for concurrent operations, including error propagation and cancellation. - **Usage**: ```python async with ManagedTaskGroup() as tg: task1 = tg.create_task(async_operation_1()) task2 = tg.create_task(async_operation_2()) await tg.join() ``` - **When to Use**: For managing a set of related async tasks where coordinated execution, error handling, or cancellation is required. Decorator: @register_collector - **Description**: Decorator to register collector instances with the main exporter application. Includes complete examples of its usage and the registration flow, showing how collectors are discovered and initialized. - **Usage**: ```python from core.collector_registry import register_collector @register_collector class MyNewCollector: # ... collector implementation ... pass ``` - **Registration Flow**: Explains how the decorator adds the collector class to a registry, which is later used to instantiate and run all collectors. ``` -------------------------------- ### Complete Collector Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/core/CLAUDE.md A comprehensive example of a Meraki Dashboard Exporter collector, demonstrating metric initialization, error handling, logging, and metric updates using domain models and enums. ```python from prometheus_client import Gauge from ..core.collector import MetricCollector, register_collector from ..core.constants.metrics_constants import MetricName from ..core.metrics import LabelName from ..core.error_handling import with_error_handling from ..core.logging_decorators import log_api_call from ..core.domain_models import Device @register_collector(UpdateTier.MEDIUM) class ExampleCollector(MetricCollector): def _initialize_metrics(self) -> None: self.device_count = Gauge( MetricName.DEVICE_COUNT.value, "Number of devices per organization", [LabelName.ORG_ID.value, LabelName.DEVICE_TYPE.value] ) @with_error_handling("Count devices", continue_on_error=True) @log_api_call("getOrganizationDevices") async def _collect_impl(self) -> None: organizations = await self._get_organizations() for org in organizations: devices = await self._fetch_devices(org.id) self._update_metrics(org.id, devices) def _update_metrics(self, org_id: str, devices: list[Device]) -> None: device_counts = {} for device in devices: device_counts[device.product_type] = device_counts.get(device.product_type, 0) + 1 for device_type, count in device_counts.items(): self.device_count.labels( org_id=org_id, device_type=device_type ).set(count) ``` -------------------------------- ### Docker Compose Configuration for OTEL Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/OTEL.md Example Docker Compose setup for running the Meraki Dashboard Exporter alongside an OpenTelemetry Collector. It demonstrates how to pass OTEL configuration as environment variables to the exporter service. ```yaml services: meraki-exporter: image: meraki-dashboard-exporter environment: - MERAKI_API_KEY=your_key - MERAKI_EXPORTER_OTEL__ENABLED=true - MERAKI_EXPORTER_OTEL__ENDPOINT=http://otel-collector:4317 - MERAKI_EXPORTER_OTEL__EXPORT_INTERVAL=30 - MERAKI_EXPORTER_OTEL__RESOURCE_ATTRIBUTES={"service.namespace":"monitoring","deployment.environment":"prod"} ports: - "9099:9099" otel-collector: image: otel/opentelemetry-collector-contrib:latest volumes: - ./otel-config.yaml:/etc/otel-collector-config.yaml command: ["--config=/etc/otel-collector-config.yaml"] ``` -------------------------------- ### OTEL Integration Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/TRACING.md Configure environment variables to integrate the Meraki Dashboard Exporter with different OpenTelemetry backends. These examples show how to set the endpoint and resource attributes or headers for specific providers. ```bash export MERAKI_EXPORTER_OTEL__ENDPOINT=http://datadog-agent:4317 export MERAKI_EXPORTER_OTEL__RESOURCE_ATTRIBUTES='{"env":"production","service":"meraki-exporter"}' ``` ```bash export MERAKI_EXPORTER_OTEL__ENDPOINT=https://otlp.nr-data.net:4317 export MERAKI_EXPORTER_OTEL__HEADERS='{"api-key":"YOUR_NR_LICENSE_KEY"}' ``` ```bash export MERAKI_EXPORTER_OTEL__ENDPOINT=http://aws-otel-collector:4317 export MERAKI_EXPORTER_OTEL__RESOURCE_ATTRIBUTES='{"aws.region":"us-east-1"}' ``` -------------------------------- ### Python: Aggregation Pattern Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/patterns/metric-collection-strategies.md Illustrates the aggregation pattern, which leverages pre-aggregated data provided by the API. This example shows how to fetch and map aggregated client counts directly to metrics. ```python async def collect_client_overview(self, org_id: str) -> None: """Use pre-aggregated data from API.""" # API returns aggregated client counts overview = await self.api.organizations.getOrganizationClientsOverview( org_id, timespan=300 # Last 5 minutes ) # Direct mapping to metrics self._clients_count.labels( org_id=org_id, client_type="wireless" ).set(overview["counts"]["wireless"]) ``` -------------------------------- ### Adding a New Service Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/CLAUDE.md Illustrates the pattern for adding a new service within the exporter package, showing how to use relative imports for core components like logging. ```python # src/meraki_dashboard_exporter/services/my_service.py from ..core.logging import get_logger logger = get_logger(__name__) class MyService: def __init__(self): logger.info("Service initialized") ``` -------------------------------- ### Factory Usage Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/tests/CLAUDE.md Illustrates how to use factories to generate realistic test data for various Meraki components. Examples include creating sensor readings, multiple organizations, and devices assigned to specific networks. ```python # Create realistic sensor reading data sensor_reading = SensorReadingFactory.create( serial="Q2XX-XXXX-XXXX", temperature=23.5, humidity=45.2, timestamp="2024-01-15T10:30:00Z" ) # Create multiple organizations for multi-org testing orgs = OrganizationFactory.create_many(3) # Create devices with specific network assignment network_devices = DeviceFactory.create_many( 5, network_id="N_123456789", product_type="MS" ) ``` -------------------------------- ### TraceQL Query Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/TRACING.md Examples of queries using TraceQL to find specific traces within the OpenTelemetry data. These queries help in identifying performance issues, errors, or traces related to specific entities. ```traceql # Find slow API calls: {service.name="meraki-dashboard-exporter" && duration > 1s} # Find failed requests: {service.name="meraki-dashboard-exporter" && status.code=ERROR} # Track specific organization: {service.name="meraki-dashboard-exporter" && org.id="123456"} ``` -------------------------------- ### Meraki Metric Query Examples (PromQL) Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/metrics/overview.md Demonstrates practical PromQL queries for analyzing Meraki metrics collected by the exporter. It covers essential patterns like calculating rates over time, filtering metrics using labels, and aggregating data to gain insights into network performance and status. ```promql # Good: Rate calculation over 5 minutes rate(meraki_org_usage_total_kb[5m]) # Good: Alert on missing data up{job="meraki"} == 0 # Filter by organization meraki_device_up{org_name="Production"} # Filter by device type meraki_device_up{device_model=~"MS.*"} # Total devices by type sum by (device_model) (meraki_device_up) # Average temperature by location avg by (network_name) (meraki_mt_temperature_celsius) ``` -------------------------------- ### Data Factory Usage Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/tests/CLAUDE.md Shows practical examples of using data factories to create test data. It covers creating single instances, multiple instances with variations, and organizations with specific attributes for use in tests. ```python # Create single realistic device device = DeviceFactory.create( serial="Q2XX-XXXX-XXXX", product_type="MR", name="Office AP" ) # Create multiple devices with variations devices = DeviceFactory.create_many(5, product_type="MS") # Create organization with specific attributes org = OrganizationFactory.create( id="123456", name="Test Organization" ) ``` -------------------------------- ### Meraki Exporter OTEL Logging Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/OTEL.md Illustrative log messages from the Meraki Dashboard Exporter indicating successful initialization and synchronization of OpenTelemetry metrics. ```log INFO: Initialized Prometheus to OpenTelemetry bridge endpoint=http://localhost:4317 service_name=meraki-dashboard-exporter export_interval=60 INFO: Started OpenTelemetry metric export endpoint=http://localhost:4317 interval=60 DEBUG: Successfully synced metrics to OpenTelemetry metric_count=150 ``` -------------------------------- ### Complete Device Collector Example with Metrics and Error Handling Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/collectors/CLAUDE.md A comprehensive example of a device collector, demonstrating metric initialization, asynchronous collection logic with error handling, and API call logging. It fetches organizations, processes them, and collects signal strength data for specific device types. ```python from prometheus_client import Gauge from ..core.collector import register_collector, UpdateTier from ..core.constants.metrics_constants import MetricName from ..core.metrics import LabelName from ..core.error_handling import with_error_handling from ..core.logging_decorators import log_api_call from .base import BaseDeviceCollector @register_collector(UpdateTier.MEDIUM) class ExampleDeviceCollector(BaseDeviceCollector): """Collector for example device metrics""" def _initialize_metrics(self) -> None: self.signal_strength = Gauge( MetricName.SIGNAL_STRENGTH.value, "Device signal strength in dBm", [LabelName.ORG_ID.value, LabelName.SERIAL.value] ) @with_error_handling("Collect device metrics", continue_on_error=True) async def _collect_impl(self) -> None: organizations = await self._get_organizations() for org in organizations: await self._process_organization(org.id) @log_api_call("getOrganizationDevicesSignalStrength") async def _process_organization(self, org_id: str) -> None: devices = await self._fetch_devices(org_id, product_types=["MR"]) for device in devices: signal_data = await self._fetch_signal_strength(device.serial) if signal_data: self.signal_strength.labels( org_id=org_id, serial=device.serial ).set(signal_data.strength) ``` -------------------------------- ### Meraki API Client Usage Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/api/CLAUDE.md Demonstrates proper patterns for using the Meraki API client within an asynchronous Python application. It includes methods for fetching organizations, devices, and wireless channel utilization, showcasing error handling and logging decorators. ```python import asyncio from typing import Optional from ..core.logging_decorators import log_api_call from ..core.error_handling import with_error_handling, ErrorCategory from ..core.domain_models import Device, Organization class ExampleCollector(MetricCollector): """Example showing proper API client usage patterns""" @with_error_handling("Fetch organizations", continue_on_error=False) @log_api_call("getOrganizations") async def _get_organizations(self) -> list[Organization]: """Get all organizations for the API key""" self._track_api_call("getOrganizations") try: orgs_data = await asyncio.to_thread( self.api.organizations.getOrganizations ) return [Organization.model_validate(org) for org in orgs_data] except Exception as e: self.logger.error(f"Failed to fetch organizations: {e}") raise @with_error_handling("Fetch devices", continue_on_error=True) @log_api_call("getOrganizationDevices") async def _fetch_devices(self, org_id: str, product_types: Optional[list[str]] = None) -> list[Device]: """Fetch devices for organization, optionally filtered by product type""" self._track_api_call("getOrganizationDevices") try: params = {"total_pages": "all"} if product_types: params["product_types"] = product_types devices_data = await asyncio.to_thread( self.api.organizations.getOrganizationDevices, org_id, **params ) return [Device.model_validate(device) for device in devices_data] except Exception as e: self.logger.error(f"Failed to fetch devices for org {org_id}: {e}") return [] @log_api_call("getOrganizationWirelessDevicesChannelUtilization") async def _fetch_channel_utilization(self, org_id: str) -> dict: """Fetch wireless channel utilization data""" self._track_api_call("getOrganizationWirelessDevicesChannelUtilization") try: return await asyncio.to_thread( self.api.wireless.getOrganizationWirelessDevicesChannelUtilization, org_id, total_pages="all", timespan=3600 ) except Exception as e: self.logger.error(f"Failed to fetch channel utilization: {e}") return {} ``` -------------------------------- ### Metric Assertion Examples Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/tests/CLAUDE.md Demonstrates how to use MetricAssertions for validating collected metrics. Examples include checking if a metric exists, verifying its specific value with labels, and confirming that a metric does not exist. ```python # Check metric exists metrics.assert_gauge_exists("meraki_device_up") # Check specific metric value metrics.assert_gauge_value("meraki_device_up", 1, org_id="123", serial="Q2XX-XXXX-XXXX") # Check metric does not exist metrics.assert_no_gauge_exists("invalid_metric") # Check metric with partial labels metrics.assert_gauge_value("meraki_channel_utilization", 45.2, serial="Q2XX-XXXX-XXXX") ``` -------------------------------- ### Jinja2 Template Structure Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/templates/cardinality.html Example Jinja2 template syntax used for iterating and displaying metrics, labels, and growth rates. Includes conditional rendering and formatting. ```jinja2 {% if report.top_metrics %} Search: {% for metric in report.top_metrics %} {% endfor %} Metric Name Cardinality Type Labels (Count) Growth Rate Documentation {{ metric.name }} {{ "{:,}".format(metric.cardinality) }} {{ metric.type }} **({{ metric.label_count }})** {% for label in metric.labels %} {{ label }} {% endfor %} {% if metric.name in report.growth_rate %} {% set growth = report.growth_rate[metric.name] %} {{ growth }}% {% else %} N/A {% endif %} {{ metric.documentation[:100] }}{% if metric.documentation|length > 100 %}...{% endif %} {% else %} ⏳ No metric data available yet. Collectors are still gathering data. This page will refresh automatically when data becomes available. {% endif %} {% if report.high_cardinality_labels %} Search: {% for label in report.high_cardinality_labels %} {% endfor %} Label Name Total Cardinality Max Single Metric Used in Metrics Example Metrics {{ label.label }} {{ "{:,}".format(label.total_cardinality) }} {{ "{:,}".format(label.max_cardinality) }} {{ label.metric_count }} {% for metric in label.example_metrics %} {{ metric }}{% if not loop.last %}, {% endif %} {% endfor %} {% else %} ⏳ No label data available yet. Collectors are still gathering data. This page will refresh automatically when data becomes available. {% endif %} {% if report.growth_rate %} Growth rates calculated over the last 10 minutes. Positive values indicate increasing cardinality. Search: {% for metric_name, growth in report.growth_rate.items() %} {% if growth != 0 %} {% endif %} {% endfor %} Metric Name Growth Rate Current Cardinality {{ metric_name }} {{ growth }}% {% set current_cardinality = namespace(value="N/A") %} {% for metric in report.top_metrics %} {% if metric.name == metric_name %} {% set current_cardinality.value = "{:,}".format(metric.cardinality) %} {% endif %} {% endfor %} {{ current_cardinality.value }} {% endif %} [View All Metrics](/cardinality/all-metrics) [View All Labels](/cardinality/all-labels) [Export as JSON](/cardinality/export/json) {% endif %} ``` -------------------------------- ### JavaScript Initialization Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/templates/cardinality_all_metrics.html Initializes table functionality upon page load. It sets up the sorting, filtering, and pagination features by calling their respective setup functions. ```javascript document.addEventListener('DOMContentLoaded', () => { makeTableSortable('metrics-table'); setupTableFilter(); updatePagination(); }); ``` -------------------------------- ### OTEL Collector Configuration Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/OTEL.md An example `otel-config.yaml` file for an OpenTelemetry Collector. It defines receivers (OTLP), processors (batch), and exporters (Prometheus, Jaeger, OTLP HTTP) for processing metrics and traces. ```yaml receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 processors: batch: exporters: prometheus: endpoint: "0.0.0.0:8889" jaeger: endpoint: jaeger:14250 tls: insecure: true otlphttp: endpoint: https://your-backend.com/v1/metrics service: pipelines: metrics: receivers: [otlp] processors: [batch] exporters: [prometheus, otlphttp] ``` -------------------------------- ### Add New Collector Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/collectors.md Demonstrates how to create and register a new custom collector in the meraki-dashboard-exporter. It shows the necessary imports, decorator usage, metric initialization, and the asynchronous collection implementation with error handling. ```python from ..core.collector import register_collector, MetricCollector, UpdateTier from ..core.constants.metrics_constants import MetricName from ..core.error_handling import with_error_handling @register_collector(UpdateTier.MEDIUM) class MyCollector(MetricCollector): """My custom collector for specific metrics.""" def _initialize_metrics(self) -> None: self.my_metric = self._create_gauge( MetricName.MY_METRIC, "Description of my metric" ) @with_error_handling('Collect my data') async def _collect_impl(self) -> None: # Collection logic here pass ``` -------------------------------- ### OpenTelemetry Collector Configuration Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/TRACING.md A sample configuration file for an OpenTelemetry Collector, demonstrating how to receive OTLP data, process it with batching and tail-based sampling policies, and export it to Jaeger and an OTLP HTTP endpoint. ```yaml receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 processors: batch: timeout: 1s send_batch_size: 1024 tail_sampling: decision_wait: 10s num_traces: 100 expected_new_traces_per_sec: 10 policies: - name: errors-policy type: status_code status_code: {status_code: ERROR} - name: slow-traces-policy type: latency latency: {threshold_ms: 1000} - name: probabilistic-policy type: probabilistic probabilistic: {sampling_percentage: 10} exporters: jaeger: endpoint: jaeger:14250 tls: insecure: true otlphttp: endpoint: https://your-backend.com/v1/traces service: pipelines: traces: receivers: [otlp] processors: [batch, tail_sampling] exporters: [jaeger, otlphttp] ``` -------------------------------- ### Span Metrics Example Queries Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/TRACING.md PromQL queries to analyze the RED (Rate, Errors, Duration) metrics automatically generated by the Meraki Dashboard Exporter from trace spans. These examples demonstrate how to calculate request rates, error percentages, and latency percentiles. ```promql # Request rate by collector rate(meraki_span_requests_total[5m]) ``` ```promql # Error rate percentage sum(rate(meraki_span_errors_total[5m])) by (collector) / sum(rate(meraki_span_requests_total[5m])) by (collector) * 100 ``` ```promql # P99 latency by operation histogram_quantile(0.99, sum(rate(meraki_span_duration_seconds_bucket[5m])) by (operation, le) ) ``` -------------------------------- ### Python: Batch Collection Pattern Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/patterns/metric-collection-strategies.md Provides an example of the batch collection pattern, used for processing multiple items of the same type efficiently. It includes batching, concurrent task execution, and delays between batches to manage API load. ```python async def _collect_impl(self) -> None: """Batch collection example.""" organizations = await self._fetch_organizations() # Process in batches to avoid overwhelming API for i in range(0, len(devices), self.settings.api.batch_size): batch = devices[i:i + self.settings.api.batch_size] # Process batch concurrently async with ManagedTaskGroup("device_batch") as group: for device in batch: await group.create_task( self._collect_device_metrics(device) ) # Delay between batches if i + self.settings.api.batch_size < len(devices): await asyncio.sleep(self.settings.api.batch_delay) ``` -------------------------------- ### Common PromQL Query Patterns Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/metrics/metrics.md Provides examples of common PromQL query patterns for analyzing Meraki network data, including device health, network utilization, and alert summaries. ```promql # Device health overview avg(meraki_device_up) by (org_name) # Network utilization rate(meraki_network_traffic_bytes_total[5m]) # Alert summary sum(meraki_alerts_total) by (severity, type) ``` -------------------------------- ### Workflow for Adding a New Collector Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/collectors/CLAUDE.md A step-by-step guide for developers on how to add a new collector for Meraki devices. It covers choosing the correct inheritance, defining metrics, implementing collection logic, registration, testing, and documentation. ```markdown ## ADDING NEW COLLECTOR 1. **Choose inheritance**: `MetricCollector`, `BaseDeviceCollector`, or other base 2. **Select update tier**: Based on data volatility and importance 3. **Define metrics** in `_initialize_metrics()` using enums 4. **Implement collection** in `_collect_impl()` with error handling 5. **Register collector**: Auto via decorator or manual in coordinator 6. **Add tests** with factories and metric assertions 7. **Update documentation** if adding new metric types ``` -------------------------------- ### Meraki Exporter Entry Points Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/CLAUDE.md Demonstrates how to run the Meraki Dashboard Exporter from the command line using `python -m` and how to programmatically create the FastAPI application instance. ```python # CLI usage python -m meraki_dashboard_exporter # Programmatic usage from meraki_dashboard_exporter.app import create_app app = create_app() ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/AGENTS.md Builds and serves the project's documentation locally using a static site generator or similar tool. This allows for easy previewing of documentation changes. ```bash make docs-serve ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/CLAUDE.md Builds and serves the project's documentation locally using a static site generator or similar tool. This allows for easy previewing of documentation changes. ```bash make docs-serve ``` -------------------------------- ### Python: Time-Series Collection Pattern Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/patterns/metric-collection-strategies.md Presents the time-series collection pattern for historical data. This example shows fetching usage history over a specific timespan and processing the most recent data point. ```python async def collect_usage_history(self, serial: str) -> None: """Collect time-series data.""" # Get last 5 minutes of data usage = await self.api.devices.getDeviceUsageHistory( serial, timespan=300 ) # Process latest data point if usage: latest = usage[-1] # Most recent self._set_usage_metrics(serial, latest) ``` -------------------------------- ### Meraki API Client: Fetch Organization Devices Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/api/CLAUDE.md Demonstrates fetching organization devices using the Meraki API client. It utilizes `asyncio.to_thread` to run the synchronous Meraki SDK call in a separate thread, ensuring non-blocking behavior. Includes application of logging decorators for monitoring API interactions. ```python import asyncio from ..core.logging_decorators import log_api_call class SomeCollector(MetricCollector): @log_api_call("getOrganizationDevices") async def _fetch_devices(self, org_id: str) -> list[Device]: self._track_api_call("getOrganizationDevices") # Always use asyncio.to_thread for API calls devices_data = await asyncio.to_thread( self.api.organizations.getOrganizationDevices, org_id, total_pages="all" # When supported ) return [Device.model_validate(device) for device in devices_data] ``` -------------------------------- ### Manual Release Steps (Bash/Git) Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/RELEASE.md Outlines the manual steps required for releasing the project, involving direct manipulation of version files, Git commits, tags, and pushing to the remote repository. ```bash # Update version in pyproject.toml # Run `uv lock` to update lock file git commit -am "chore: bump version to X.Y.Z" git tag -a vX.Y.Z -m "Release version X.Y.Z" git push origin main --tags ``` -------------------------------- ### Meraki Collector Registration Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/collectors.md Illustrates the registration of a collector with a specific update tier using a decorator. This pattern is common for defining and managing data collection modules. ```Python from meraki_dashboard_exporter.collector import register_collector, UpdateTier # Example of a collector class definition (OrganizationCollector) # ... other imports and class definition ... @register_collector(UpdateTier.MEDIUM) class OrganizationCollector(MetricCollector): # ... collector implementation ... pass # The text mentions this collector is defined at Line 31 and collects 8 metrics. ``` -------------------------------- ### Cosign Container Image Verification and SBOM Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/SECURITY.md Demonstrates how to use `cosign` to verify container image signatures, download the Software Bill of Materials (SBOM), and verify build attestations. These commands ensure the integrity and provenance of the container images. ```bash # Verify container signature cosign verify ghcr.io/rknightion/meraki-dashboard-exporter:latest \ --certificate-identity-regexp "https://github.com/rknightion/meraki-dashboard-exporter/.github/workflows/docker-build.yml@refs/heads/main" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" ``` ```bash # Download and inspect SBOM cosign download sbom ghcr.io/rknightion/meraki-dashboard-exporter:latest ``` ```bash # Verify attestations cosign verify-attestation ghcr.io/rknightion/meraki-dashboard-exporter:latest \ --type slsaprovenance \ --certificate-identity-regexp "https://github.com/rknightion/meraki-dashboard-exporter/.github/workflows/docker-build.yml@refs/heads/main" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" ``` -------------------------------- ### Python: Hierarchical Collection Pattern Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/patterns/metric-collection-strategies.md Demonstrates the hierarchical collection pattern, suitable for data with parent-child relationships. It shows how to traverse through different levels, such as organizations, networks, and devices, to collect metrics. ```python async def _collect_impl(self) -> None: """Hierarchical collection example.""" # Level 1: Organizations for org in organizations: # Level 2: Networks networks = await self._fetch_networks(org["id"]) for network in networks: # Level 3: Devices devices = await self._fetch_devices(network["id"]) # Collect metrics at appropriate level self._set_network_metrics(network, len(devices)) ``` -------------------------------- ### GitHub CLI for Release Creation (Bash) Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/RELEASE.md Demonstrates using the GitHub CLI (`gh`) to create a new GitHub release from a Git tag, automatically generating release notes based on commit history. ```bash gh release create vX.Y.Z --generate-notes ``` -------------------------------- ### Run All Tests Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/CLAUDE.md Executes the complete test suite for the project using pytest. This is crucial for verifying the functionality and stability of the exporter. ```bash uv run pytest ``` -------------------------------- ### Run All Tests Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/AGENTS.md Executes the complete test suite for the project using pytest. This is crucial for verifying the functionality and stability of the exporter. ```bash uv run pytest ``` -------------------------------- ### Python Response Validation Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/adr/002-error-handling-strategy.md Demonstrates how to validate the format of an API response using a utility function. This ensures that the received data conforms to the expected structure, preventing downstream issues caused by malformed or unexpected data. ```python devices = validate_response_format( devices, expected_type=list, operation="getOrganizationDevices" ) ``` -------------------------------- ### Auto-refresh page on data readiness Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/templates/cardinality.html This JavaScript snippet automatically refreshes the page every 5 seconds when initial data collection is pending. It ensures the user sees the latest information once data is ready, improving the user experience during the initial setup phase. ```javascript setTimeout(() => { window.location.reload(); }, 5000); // Refresh every 5 seconds until data is ready ``` -------------------------------- ### Makefile Release Process Steps (Makefile) Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/RELEASE.md Details the sequence of automated actions performed by the Makefile release commands, including pre-release checks, dependency updates, version bumping, Git commits and tagging, and pushing to GitHub. ```makefile 1. Pre-release checks: Runs `make check` (lint, typecheck, tests) 2. Update dependencies: Runs `uv lock` to ensure lock file is current 3. Bump version: Updates version in `pyproject.toml` 4. Commit changes: Commits version bump and updated lock file 5. Create git tag: Tags the commit with `v{version}` 6. Push to GitHub: Pushes commits and tags (with confirmation) 7. Create GitHub release: Uses `gh` CLI to create release with auto-generated notes ``` -------------------------------- ### Collect Meraki Switch (MS) Metrics Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/src/meraki_dashboard_exporter/collectors/devices/CLAUDE.md Example Python code for collecting switch port status and PoE power metrics from Meraki Switches (MS). It inherits from BaseDeviceCollector and defines specific metrics for switch ports. ```python class MSCollector(BaseDeviceCollector): """Collector for MS (Switches) devices""" def _initialize_metrics(self) -> None: self.port_status = Gauge( MetricName.PORT_STATUS.value, "Switch port status (1=up, 0=down)", [LabelName.ORG_ID.value, LabelName.SERIAL.value, LabelName.PORT.value] ) self.poe_power = Gauge( MetricName.POE_POWER.value, "PoE power consumption in watts", [LabelName.ORG_ID.value, LabelName.SERIAL.value, LabelName.PORT.value] ) async def _collect_impl(self) -> None: organizations = await self._get_organizations() for org in organizations: devices = await self._fetch_devices(org.id, product_types=["MS"]) await self._collect_port_status(org.id, devices) await self._collect_poe_metrics(org.id, devices) ``` -------------------------------- ### Python Collector Registration Example Source: https://github.com/rknightion/meraki-dashboard-exporter/blob/main/docs/adr/001-collector-architecture.md Demonstrates the pattern for registering a new collector in Python using a decorator. It shows how a custom collector class inherits from a base class and is associated with a specific update tier, facilitating auto-registration within the system. ```python @register_collector(UpdateTier.MEDIUM) class MyCollector(MetricCollector): pass ```