---
title: Charmhub | Deploy Prometheus using Charmhub - The Open Operator Collection
description: Deploy the latest version of Prometheus as a Kubernetes Operator on any
  cloud.
url: https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write
---

# Prometheus

[Canonical Observability](https://charmhub.io/publisher/observability "View all packages from Canonical Observability")

* [Canonical Observability](https://charmhub.io/publisher/observability "View all packages from Canonical Observability")

Platform:

3.11/stable tf-3.11.1-1-g7307c58

```
juju deploy prometheus-k8s --channel 3.11/stable
```

[Learn to deploy on juju >](https://juju.is/docs/juju/manage-applications)

[Toggle side navigation](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#drawer)

## charms.prometheus\_k8s.v1.prometheus\_remote\_write

* [*Docstrings*Docstrings](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write)
  [*Code*Source code](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write/source-code)
* + Download

    Fetch library

    ```
    charmcraft fetch-lib charms.prometheus_k8s.v1.prometheus_remote_write
    ```

    [Download prometheus\_remote\_write.py](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write/download)
  + *Last updated* 10 Sep 2026
  + *Revision* Library version 1.19

#### Prometheus remote-write library.

This library facilitates the integration of the prometheus\_remote\_write interface.

Source code can be found on GitHub at:
https://github.com/canonical/prometheus-k8s-operator/tree/main/lib/charms/prometheus\_k8s

Charms that need to push data to a charm exposing the Prometheus remote\_write API,
should use the `PrometheusRemoteWriteConsumer`. Charms that operate software that exposes
the Prometheus remote\_write API, that is, they can receive metrics data over remote\_write,
should use the `PrometheusRemoteWriteProducer`.

##### Alert rules encoding

The consumer publishes its alert rules to the `alert_rules` key of its application
databag. Because large deployments can produce enough alert rules to exceed Juju's
relation data size limit, the rules can be stored LZMA-compressed and base64-encoded
instead of as plain JSON.

Compression is negotiated over the relation: the provider advertises the encodings it
is able to read in the `alert_rules_encodings` key of its own application databag, and
the consumer picks the best encoding both sides support. A consumer related to a
provider running an older version of this library (which advertises nothing) keeps
writing plain JSON, so upgrades are safe in any order.

An admin can decode compressed rules with:

```
<alert-rules-from-show-unit> | base64 -d | xz -d | jq
```

---

Index

* [class RelationNotFoundError](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#relationnotfounderror)
* + [def \_\_init\_\_(
    self,
    relation\_name)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#relationnotfounderror-__init__)
* [class RelationInterfaceMismatchError](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#relationinterfacemismatcherror)
* + [def \_\_init\_\_(
    self,
    relation\_name,
    expected\_relation\_interface,
    actual\_relation\_interface)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#relationinterfacemismatcherror-__init__)
* [class RelationRoleMismatchError](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#relationrolemismatcherror)
* + [def \_\_init\_\_(
    self,
    relation\_name,
    expected\_relation\_role,
    actual\_relation\_role)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#relationrolemismatcherror-__init__)
* [class InvalidAlertRuleEvent](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#invalidalertruleevent)
* + [def \_\_init\_\_(
    self,
    handle,
    errors,
    valid)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#invalidalertruleevent-__init__)
* + [def snapshot(
    self)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#invalidalertruleevent-snapshot)
* + [def restore(
    self,
    snapshot)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#invalidalertruleevent-restore)
* [class PrometheusRemoteWriteEndpointsChangedEvent](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteendpointschangedevent)
* + [def \_\_init\_\_(
    self,
    handle,
    relation\_id)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteendpointschangedevent-__init__)
* + [def snapshot(
    self)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteendpointschangedevent-snapshot)
* + [def restore(
    self,
    snapshot)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteendpointschangedevent-restore)
* [class InvalidAlertRulePathError](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#invalidalertrulepatherror)
* + [def \_\_init\_\_(
    self,
    alert\_rules\_absolute\_path,
    message)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#invalidalertrulepatherror-__init__)
* [class PrometheusRemoteWriteConsumerEvents](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteconsumerevents)
* [class PrometheusRemoteWriteConsumer](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteconsumer)
* + [def \_\_init\_\_(
    self,
    charm,
    relation\_name,
    alert\_rules\_path,
    refresh\_event)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteconsumer-__init__)
* + [def reload\_alerts(
    self)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteconsumer-reload_alerts)
* + [def endpoints(
    self)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteconsumer-endpoints)
* [class PrometheusRemoteWriteAlertsChangedEvent](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewritealertschangedevent)
* + [def \_\_init\_\_(
    self,
    handle,
    relation\_id)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewritealertschangedevent-__init__)
* + [def snapshot(
    self)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewritealertschangedevent-snapshot)
* + [def restore(
    self,
    snapshot)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewritealertschangedevent-restore)
* [class PrometheusRemoteWriteProviderConsumersChangedEvent](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteproviderconsumerschangedevent)
* [class PrometheusRemoteWriteProviderEvents](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteproviderevents)
* [class PrometheusRemoteWriteProvider](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteprovider)
* + [def \_\_init\_\_(
    self,
    charm,
    relation\_name)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteprovider-__init__)
* + [def update\_endpoint(
    self,
    relation)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteprovider-update_endpoint)
* + [def alerts(
    self)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteprovider-alerts)
* + [def has\_invalid\_alert\_rules(
    self)](https://charmhub.io/prometheus-k8s/libraries/prometheus_remote_write#prometheusremotewriteprovider-has_invalid_alert_rules)

#### class RelationNotFoundError

Description

Raised if there is no relation with the given name. None

Methods

RelationNotFoundError.
\_\_init\_\_(

*self*

,
relation\_name: str
)

#### class RelationInterfaceMismatchError

Description

Raised if the relation with the given name has a different interface. None

Methods

RelationInterfaceMismatchError.
\_\_init\_\_(

*self*

,
relation\_name: str

,
expected\_relation\_interface: str

,
actual\_relation\_interface: str
)

#### class RelationRoleMismatchError

Description

Raised if the relation with the given name has a different direction. None

Methods

RelationRoleMismatchError.
\_\_init\_\_(

*self*

,
relation\_name: str

,
expected\_relation\_role: RelationRole

,
actual\_relation\_role: RelationRole
)

#### class InvalidAlertRuleEvent

Event emitted when alert rule files are not parsable.

Description

Enables us to set a clear status on the provider.

Methods

InvalidAlertRuleEvent.
\_\_init\_\_(

*self*

,
handle

,
errors: str

,
valid: bool
)

InvalidAlertRuleEvent.
snapshot(

*self*
)

Description

Save alert rule information. None

InvalidAlertRuleEvent.
restore(

*self*

,
snapshot
)

Description

Restore alert rule information. None

#### class PrometheusRemoteWriteEndpointsChangedEvent

Description

Event emitted when Prometheus remote\_write endpoints change. None

Methods

PrometheusRemoteWriteEndpointsChangedEvent.
\_\_init\_\_(

*self*

,
handle

,
relation\_id
)

PrometheusRemoteWriteEndpointsChangedEvent.
snapshot(

*self*
)

Description

Save scrape Prometheus remote\_write information. None

PrometheusRemoteWriteEndpointsChangedEvent.
restore(

*self*

,
snapshot
)

Description

Restore scrape Prometheus remote\_write information. None

#### class InvalidAlertRulePathError

Description

Raised if the alert rules folder cannot be found or is otherwise invalid. None

Methods

InvalidAlertRulePathError.
\_\_init\_\_(

*self*

,
alert\_rules\_absolute\_path: str

,
message: str
)

#### class PrometheusRemoteWriteConsumerEvents

Description

Event descriptor for events raised by `PrometheusRemoteWriteConsumer`. None

#### class PrometheusRemoteWriteConsumer

API that manages a required `prometheus_remote_write` relation.

Description

The `PrometheusRemoteWriteConsumer` is intended to be used by charms that need to push data to
other charms over the Prometheus remote\_write API.

The `PrometheusRemoteWriteConsumer` object can be instantiated as follows in your charm:

```
from charms.prometheus_k8s.v1.prometheus_remote_write import PrometheusRemoteWriteConsumer

def __init__(self, *args):
    ...
    self.remote_write_consumer = PrometheusRemoteWriteConsumer(self)
    ...
```

The `PrometheusRemoteWriteConsumer` assumes that, in the `metadata.yaml` of your charm,
you declare a required relation as follows:

```
requires:
    send-remote-write:  # Relation name
        interface: prometheus_remote_write  # Relation interface
```

The charmed operator is expected to use the `PrometheusRemoteWriteConsumer` as follows:

```
def __init__(self, *args):
    ...
    self.remote_write_consumer = PrometheusRemoteWriteConsumer(self)
    ...

    self.framework.observe(
        self.remote_write_consumer.on.endpoints_changed,
        self._handle_endpoints_changed,
    )
```

The `endpoints_changed` event will fire in situations such as provider ip change (e.g.
relation created, provider upgrade, provider pod churn) or provider config change (e.g.
metadata settings).

Then, inside the logic of `_handle_endpoints_changed`, the updated endpoint list is
retrieved with:

```
self.remote_write_consumer.endpoints
```

which returns a dictionary structured like the Prometheus configuration object (see
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote\_write).

Regarding the default relation name, `send-remote-write`: if you choose to change it,
you would need to explicitly provide it to the `PrometheusRemoteWriteConsumer` via the
`relation_name` constructor argument. (The relation interface, on the other hand, is
fixed and, if you were to change it, your charm would not be able to relate with other
charms using the correct relation interface. The library prevents you from doing that by
raising an exception.)

In any case, it is strongly discouraged to change the relation name: having consistent
relation names across charms that do similar things is good practice and more
straightforward for the users of your charm. The one exception to the rule above,
is if your charm needs to both consume and provide a relation using the
`prometheus_remote_write` interface, in which case changing the relation name to
differentiate between "incoming" and "outgoing" remote write interactions is necessary.

It is also possible to specify alert rules. By default, this library will search
`<charm_parent_dir>/prometheus_alert_rules`, which in standard charm
layouts resolves to `src/prometheus_alert_rules`. Each set of alert rules, grouped
by the topology identifier, goes into a separate `*.rule` file.

If the syntax of a rule is invalid, the `MetricsEndpointProvider` logs an error and
does not load the particular rule.

The alert rules are published to the `alert_rules` key of this application's databag,
LZMA-compressed and base64-encoded if the provider advertises that it can read them
that way, and as plain JSON otherwise. See the module docstring for details.

To avoid false positives and false negatives the library will inject label filters
automatically in the PromQL expression. For example if the charm provides an
alert rule with an `expr` like this one:

```
expr: up < 1
```

it will be modified with label filters ensuring that
the only timeseries evaluated are those scraped from this charm, and no other.

```
expr: up{juju_application="traefik",
         juju_charm="traefik-k8s",
         juju_model="cos",
         juju_model_uuid="b5ed878d-2671-42e8-873a-e8d58c0ec325"
      } < 1
labels:
  juju_application: traefik
  juju_charm: traefik-k8s
  juju_model: cos
  juju_model_uuid: b5ed878d-2671-42e8-873a-e8d58c0ec325
```

Methods

PrometheusRemoteWriteConsumer.
\_\_init\_\_(

*self*

,
charm: CharmBase

,
relation\_name: str

,
alert\_rules\_path: str

,
refresh\_event
)

API to manage a required relation with the `prometheus_remote_write` interface.

Arguments

charm

The charm object that instantiated this class.

relation\_name

Name of the relation with the `prometheus_remote_write` interface as
defined in metadata.yaml.

alert\_rules\_path

Path of the directory containing the alert rules.

refresh\_event

an optional bound event or list of bound events which
will be observed to re-set alerts data.

peer\_relation\_name

Name of the peer relation containing units of this charm.

forward\_alert\_rules

Flag to toggle forwarding of charmed alert rules.

extra\_alert\_labels

Dict of extra labels to inject alert rules with.

Description

Since remote write consumers need to inject labels into alert expressions, they need
to have the cos tool binary available.

PrometheusRemoteWriteConsumer.
reload\_alerts(

*self*
)

Description

Reload alert rules from disk and push to relation data. None

PrometheusRemoteWriteConsumer.
endpoints(

*self*
)

A config object ready to be dropped into a prometheus config file.

Returns

A list of dictionaries where each dictionary provides information about
a single remote\_write endpoint.

Description

The endpoints are deduplicated.

The format of the dict is specified in the official prometheus docs:
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote\_write

#### class PrometheusRemoteWriteAlertsChangedEvent

Description

Event emitted when Prometheus remote\_write alerts change. None

Methods

PrometheusRemoteWriteAlertsChangedEvent.
\_\_init\_\_(

*self*

,
handle

,
relation\_id
)

PrometheusRemoteWriteAlertsChangedEvent.
snapshot(

*self*
)

Description

Save Prometheus remote\_write information. None

PrometheusRemoteWriteAlertsChangedEvent.
restore(

*self*

,
snapshot
)

Description

Restore Prometheus remote\_write information. None

#### class PrometheusRemoteWriteProviderConsumersChangedEvent

Description

Event emitted when Prometheus remote\_write alerts change. None

#### class PrometheusRemoteWriteProviderEvents

Description

Event descriptor for events raised by `PrometheusRemoteWriteProvider`. None

#### class PrometheusRemoteWriteProvider

API that manages a provided `prometheus_remote_write` relation.

Description

The `PrometheusRemoteWriteProvider` is intended to be used by charms whose workloads need
to receive data from other charms' workloads over the Prometheus remote\_write API.

The `PrometheusRemoteWriteProvider` object can be instantiated as follows in your charm:

```
from charms.prometheus_k8s.v1.prometheus_remote_write import PrometheusRemoteWriteProvider

def __init__(self, *args):
    ...
    self.remote_write_provider = PrometheusRemoteWriteProvider(self)
    ...
```

The `PrometheusRemoteWriteProvider` assumes that, in the `metadata.yaml` of your charm,
you declare a provided relation as follows:

```
provides:
    receive-remote-write:  # Relation name
        interface: prometheus_remote_write  # Relation interface
```

About the name of the relation managed by this library: technically, you *could* change
the relation name, `receive-remote-write`, but that requires you to provide the new
relation name to the `PrometheusRemoteWriteProducer` via the `relation_name` constructor
argument. (The relation interface, on the other hand, is immutable and, if you were to change
it, your charm would not be able to relate with other charms using the right relation
interface. The library prevents you from doing that by raising an exception.) In any case, it
is strongly discouraged to change the relation name: having consistent relation names across
charms that do similar things is a very good thing for the people that will use your charm.
The one exception to the rule above, is if you charm needs to both consume and provide a
relation using the `prometheus_remote_write` interface, in which case changing the relation
name to differentiate between "incoming" and "outgoing" remote write interactions is necessary.

Methods

PrometheusRemoteWriteProvider.
\_\_init\_\_(

*self*

,
charm: CharmBase

,
relation\_name: str
)

API to manage a provided relation with the `prometheus_remote_write` interface.

Arguments

charm

The charm object that instantiated this class.

relation\_name

Name of the relation with the `prometheus_remote_write` interface as
defined in metadata.yaml.

server\_url\_func

A callable returning the URL for your prometheus server.

endpoint\_path

The path of the server's remote\_write endpoint.

PrometheusRemoteWriteProvider.
update\_endpoint(

*self*

,
relation
)

Triggers programmatically the update of the relation data.

Arguments

relation

An optional instance of `class:ops.model.Relation` to update.
If not provided, all instances of the `prometheus_remote_write`
relation are updated.

Description

This method should be used when the charm relying on this library needs
to update the relation data in response to something occurring outside
the `prometheus_remote_write` relation lifecycle, e.g., in case of a
host address change because the charmed operator becomes connected to an
Ingress after the `prometheus_remote_write` relation is established.

The alert rules encodings this library can read are advertised at the same
time, so that consumers know they may compress their alert rules.

PrometheusRemoteWriteProvider.
alerts(

*self*
)

Fetch alert rules from all relations.

Returns

a dictionary mapping the name of an alert rule group to the group.

Description

A Prometheus alert rules file consists of a list of "groups". Each
group consists of a list of alerts (`rules`) that are sequentially
executed. This method returns all the alert rules provided by each
related metrics provider charm. These rules may be used to generate a
separate alert rules file for each relation since the returned list
of alert groups are indexed by relation ID. Also, for each relation ID
associated scrape metadata such as Juju model, UUID and application
name are provided so the unique name may be generated for the rules
file. For each relation the structure of data returned is a dictionary
with four keys

* groups
* model
* model\_uuid
* application

The value of the `groups` key is such that it may be used to generate
a Prometheus alert rules file directly using `yaml.dump` but the
`groups` key itself must be included as this is required by Prometheus,
for example as in `yaml.safe_dump({"groups": alerts["groups"]})`.

The `PrometheusRemoteWriteProvider` accepts a list of rules and these
rules are all placed into one group.

PrometheusRemoteWriteProvider.
has\_invalid\_alert\_rules(

*self*
)

Check whether any relation reported invalid alert rules.

Returns

True if any related consumer reported alert rule validation errors,
False otherwise.

Description

Validation errors, written to relation app data by the :attr:`alerts`
property, are read back to determine whether the relation currently
carries an invalid set of alert rules.
