Skip to content

Commit

Permalink
solve config yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas committed Apr 4, 2023
1 parent ab3b828 commit de10671
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 78 deletions.
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
# MISeR
A tool for interacting with Google Cloud Monitoring.
# MISeR - A Google Cloud Monitoring Metrics Exporter

MISeR is a [Prometheus Exporter](https://prometheus.io/docs/instrumenting/exporters/#exporters-and-integrations) for [Google Cloud Monitoring](https://cloud.google.com/monitoring/) metrics.

It is written in Elixir and originated at [Massdriver](https://massdriver.cloud).

# Features

* Export metrics from Google Cloud Monitoring to Prometheus
* Simple configuration of metrics using metric type prefixes
* Auto discovery of resources via tags
* Adds any available dimension labels to metrics

# Configuration

## Authentication

The exporter is configured to use [Google Application Default Credentials](https://cloud.google.com/docs/authentication/production#automatically) to authenticate with Google Cloud Monitoring.

## Configuration

The exporter is configured using a YAML file. The following options are available:

### Required

| Option | Description |
|--------|-------------|
| `project_id` | The Google Cloud project ID to export metrics from. |
| `metric_type_prefixes` | A list of metric type prefixes to export. |

### Optional

| Option | Description |
|--------|-------------|
| `user_labels` | User-defined [labels](https://cloud.google.com/resource-manager/docs/creating-managing-labels) to filter on. |

### Example

```yaml
project_id: "massdriver"
metric_type_prefixes:
- "cloudsql.googleapis.com/database/cpu"
user_labels:
environment: "prod"
```
# Scraping
By default, the exporter is exposed on port `9090`, path `/metrics`.

Metrics are queried at the time of scraping and are not cached.
2 changes: 2 additions & 0 deletions config/prod.exs
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
import Config

config :miser, Miser.Config, file: "/config/config.yml"
2 changes: 0 additions & 2 deletions config/runtime.exs
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import Config

config :miser, Miser, YamlElixir.read_from_file!("/config/config.yml")
7 changes: 7 additions & 0 deletions config/test.exs
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
import Config

config :miser, Miser.Config,
project_id: "my_project_id",
metric_type_prefixes: ["cloudsql.googleapis.com/database/cpu"],
user_labels: %{
"environment" => "dev"
}
5 changes: 0 additions & 5 deletions config_test.yml

This file was deleted.

12 changes: 0 additions & 12 deletions credentials_test.json

This file was deleted.

8 changes: 6 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ services:
environment:
- GOOGLE_APPLICATION_CREDENTIALS=/config/credentials.json
volumes:
- ${PWD}/credentials.json:/config/credentials.json
- ${PWD}/config.yml:/config/config.yml
- type: bind
source: ./credentials.json
target: /config/credentials.json
- type: bind
source: ./config.yml
target: /config/config.yml
ports:
- "9090:9090"
44 changes: 0 additions & 44 deletions lib/env.ex

This file was deleted.

3 changes: 2 additions & 1 deletion lib/miser/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ defmodule Miser.Application do
@impl true
def start(_type, _args) do
Prometheus.Registry.register_collector(Miser.Collector)
Miser.setup()

children = [
{Plug.Cowboy, scheme: :http, plug: Miser.Router, port: 9090},
{Goth, name: Miser.Goth}
]

:ok = Miser.Config.configure()

opts = [strategy: :one_for_one, name: Miser.Supervisor]
Supervisor.start_link(children, opts)
end
Expand Down
10 changes: 4 additions & 6 deletions lib/miser/collector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,17 @@ defmodule Miser.Collector do
"""
use Prometheus.Collector

alias Miser.Client
alias Miser.{Client, Config}
alias Miser.Client.{ListMetricDescriptorsRequest, ListTimeSeriesRequest}
alias Prometheus.Model

@impl true
@spec collect_mf(any, any) :: :ok
def collect_mf(_registry, callback) do
config = Application.get_env(:miser, Miser)
project_id = Map.fetch!(config, "project_id")
user_labels = Map.get(config, "user_labels", %{})
project_id = Config.project_id()
user_labels = Config.user_labels()

config
|> Map.get("metric_type_prefixes", [])
Config.metric_type_prefixes()
# should probably parallelize this
|> Enum.each(fn metric_type_prefix ->
request = %ListMetricDescriptorsRequest{
Expand Down
43 changes: 43 additions & 0 deletions lib/miser/config.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
defmodule Miser.Config do
@moduledoc """
Managed Miser config.any()
This useful wrapper lets us evaluate config files for when this thing is configured on k8s.
"""

def configure do
Application.get_env(:miser, __MODULE__)
|> Keyword.get(:file)
|> case do
nil -> :ok
file -> evaluate_config_file(file)
end
end

def project_id do
Application.fetch_env!(:miser, __MODULE__)
|> Keyword.fetch!(:project_id)
end

def user_labels do
Application.fetch_env!(:miser, __MODULE__)
|> Keyword.get(:user_labels, [])
end

def metric_type_prefixes do
Application.fetch_env!(:miser, __MODULE__)
|> Keyword.fetch!(:metric_type_prefixes)
end

def evaluate_config_file(path) do
config_map = YamlElixir.read_from_file!(path)

config = [
project_id: Map.fetch!(config_map, "project_id"),
user_labels: Map.get(config_map, "user_labels", %{}),
metric_type_prefixes: Map.fetch!(config_map, "metric_type_prefixes")
]

Application.put_env(:miser, __MODULE__, config)
end
end
4 changes: 0 additions & 4 deletions test/env_test.exs

This file was deleted.

0 comments on commit de10671

Please sign in to comment.