# Custom Metrics in Functions

[Functions](/overview/core-concepts/function.md) enable you to define your own processing logic and make it available in SQL. This document walks you through how to add custom metrics to functions.

DeltaStream queries are powered by Apache Flink; you can implement functions as Apache Flink user-defined functions as described in the [Apache Flink documentation](https://nightlies.apache.org/flink/flink-docs-release-1.19/docs/dev/table/functions/udfs/).

See [`CREATE METRICS INTEGRATION`](/reference/sql-syntax/ddl/create-metrics-integration.md) for consuming the metrics in this document.

You can add 3 types of custom metrics (see [Flink docs on Metrics](https://nightlies.apache.org/flink/flink-docs-release-1.19/docs/ops/metrics/#registering-metrics) for more information):

1. Counter: an integer value that can be incremented or decremented.
2. Meter: a value that measures the average throughput of events over a time period.
3. Gauge: a value of any type that can be retrieved on demand. This value is set in the function's logic.

The code block below demonstrates how you can add a custom metric (counter) to a Java function:

```java
public class UdfWithMetrics extends ScalarFunction {

    // IMPORANT NOTE: For UDF metrics to be available, metric group name must be "deltastream_udf"
    private final String METRIC_GROUP = "deltastream_udf";

    private transient Counter counter;
    private transient Meter meter;
    private transient int gaugeValue = 0;

    @Override
    public void open(FunctionContext context) {
        this.counter = context.getMetricGroup()
            .addGroup(METRIC_GROUP)
            .counter("myCounter");
        this.meter = context.getMetricGroup()
            .addGroup(METRIC_GROUP)
            .meter("myMeter", new MeterView(60));
        context.getMetricGroup().addGroup(METRIC_GROUP)
            .gauge("myGauge", (Gauge<Integer>) () -> gaugeValue);
    }

    public String eval(String s) {
        if (s == null) {
            meter.markEvent();
            return null;
        }

        if (s.startsWith("Value_")) {
            try {
                int val = Integer.parseInt(s.substring(6));
                gaugeValue = val;
            } catch(NumberFormatException e){
                counter.inc();
            }
        }

        return s.replaceAll("_", " ");
    }
}
```

{% hint style="warning" %}
**Important** In the `context.getMetricGroup().addGroup(METRIC_GROUP)` method, the `METRIC_GROUP` value is `deltastream_udf`. You **must** set the metric group name to this value for the DeltaStream platform to properly scrape and make this metric available.
{% endhint %}

For the full code example, [see this example](https://github.com/deltastreaminc/deltastream-examples/blob/main/udf/java/examples/src/main/java/examples/UdfWithMetrics.java).

After [setting up a metrics integration](/reference/metrics/prometheus-integration.md), you can find your metrics with prefix `deltastream_udf`. For instance, the `myCounter` metric in the code block above has the metric name `deltastream_udf_myCounter`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.deltastream.io/reference/metrics/custom-metrics-in-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
