How to Monitor Easegress and Its Performance: A Complete Guide

Easegress exposes internal performance data through a generic metric interface that streams to Kafka, enabling real-time monitoring of request rates, latency, and custom application metrics.

To monitor Easegress and its performance effectively, you need to understand its built-in telemetry system. The open-source API gateway implements a pluggable monitoring architecture centered around the Metricer interface and the EaseMonitorMetrics controller, which together collect and forward metrics to external systems like Kafka for consumption by Prometheus, Grafana, or custom analytics platforms.

Understanding the Easegress Monitoring Architecture

The monitoring system in easegress-io/easegress follows a producer-consumer pattern where individual components expose their internal state through a standardized interface.

The Metricer Interface

All observable objects in Easegress implement the easemonitor.Metricer interface defined in pkg/util/easemonitor/easemonitor.go:

type Metricer interface {
    ToMetrics(service string) []*easemonitor.Metrics
}

(see easemonitor.go#L45-L48)

Each object—whether an HTTP server, pipeline, traffic controller, or WAF—provides its own implementation of ToMetrics. The returned Metrics structs contain common fields (timestamp, category, host, service, type, resource) and an opaque payload (OtherFields) for object-specific data like request counts or active sessions.

The EaseMonitorMetrics Controller

The EaseMonitorMetrics object acts as a business controller that periodically pulls status snapshots from the system-wide StatusSyncController. Located in pkg/object/easemonitormetrics/easemonitormetrics.go, this controller:

  1. Iterates through every service-level status snapshot
  2. Checks if the status implements easemonitor.Metricer
  3. Calls ToMetrics(service) to extract concrete metrics
  4. Enriches common fields (category, hostname, IPv4, system, timestamp)
  5. Marshals metrics to JSON and sends them to a Kafka topic

The core collection loop lives in sendMetrics:

for _, record := range emm.ssc.GetStatusSnapshots() {
    // … iterate over services …
    metricer, ok := status.ObjectStatus.(easemonitor.Metricer)
    if !ok { continue }

    for _, m := range metricer.ToMetrics(service) {
        // fill common fields
        // marshal to JSON
        client.Input() <- &sarama.ProducerMessage{Topic: emm.spec.Kafka.Topic, Value: sarama.ByteEncoder(data)}
    }
}

(see easemonitormetrics.go#L28-L57)

The controller runs on a fixed interval (statSynccontroller.SyncStatusPaceInUnixSeconds) and activates automatically when you create an EaseMonitorMetrics object in the global configuration.

Configuring Easegress Performance Monitoring

To enable monitoring, add the EaseMonitorMetrics controller to your Easegress configuration file:


# config.yaml (excerpt)

objects:
  - kind: EaseMonitorMetrics
    name: easemonitor-metrics
    kafka:
      brokers: ["kafka-01:9092", "kafka-02:9092"]
      topic: easegress-metrics

(see easemonitor-metrics-example.yaml)

Once configured, Easegress begins streaming JSON-encoded metrics to the specified Kafka topic, including data from HTTP servers, pipelines, traffic controllers, and the WAF (which exposes counters like waf_total_refused_requests).

Consuming Metrics from Kafka

Downstream consumers can subscribe to the Kafka topic to persist or visualize Easegress performance data. Here is a simple Go client that decodes the metrics:

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/Shopify/sarama"
	"github.com/megaease/easegress/v2/pkg/util/easemonitor"
)

func main() {
	config := sarama.NewConfig()
	config.Consumer.Return.Errors = true
	consumer, err := sarama.NewConsumer([]string{"127.0.0.1:9092"}, config)
	if err != nil {
		log.Fatalf("Kafka consumer error: %v", err)
	}
	defer consumer.Close()

	partition, err := consumer.ConsumePartition("easegress-metrics", 0, sarama.OffsetNewest)
	if err != nil {
		log.Fatalf("Consume partition error: %v", err)
	}
	defer partition.Close()

	ctx := context.Background()
	for {
		select {
		case msg := <-partition.Messages():
			var m easemonitor.Metrics
			if err := json.Unmarshal(msg.Value, &m); err != nil {
				log.Printf("unmarshal error: %v", err)
				continue
			}
			fmt.Printf("Metric: service=%s type=%s timestamp=%d payload=%+v\n",
				m.Service, m.Type, m.Timestamp, m.OtherFields)
		case <-ctx.Done():
			return
		}
	}
}

This consumer unmarshals the easemonitor.Metrics struct, giving you access to common fields like service name and timestamp, plus the OtherFields map containing object-specific performance data.

Adding Custom Metrics to Your Objects

If you are developing custom Easegress objects, you can expose metrics by implementing the Metricer interface. Here is an example implementation:

func (s *Status) ToMetrics(service string) []*easemonitor.Metrics {
	return []*easemonitor.Metrics{
		{
			CommonFields: easemonitor.CommonFields{
				Category: "application",
				Service:  service,
				Type:     "my_custom_metric",
				Resource: "my_resource",
			},
			OtherFields: map[string]int{"active_sessions": s.ActiveSessions},
		},
	}
}

Real-world examples exist in pipeline.Status.ToMetrics and httpserver.Status.ToMetrics, demonstrating how to expose request latency, throughput, and error rates.

Summary

  • Easegress exposes internal performance data through the easemonitor.Metricer interface implemented by all observable objects.
  • The EaseMonitorMetrics controller (pkg/object/easemonitormetrics/easemonitormetrics.go) periodically collects metrics and streams them to Kafka.
  • Configuration requires adding an EaseMonitorMetrics object to your global config with valid Kafka broker endpoints.
  • Downstream consumers can decode JSON metrics from Kafka to feed Prometheus, Grafana, or custom analytics platforms.
  • Custom objects can expose metrics by implementing ToMetrics(service string) []*easemonitor.Metrics.

Frequently Asked Questions

How do I enable Easegress performance monitoring in a production cluster?

Add the EaseMonitorMetrics controller to your global configuration file with a pointer to your Kafka cluster. The controller automatically discovers all objects implementing the Metricer interface and begins streaming metrics to the configured topic. Ensure your Kafka cluster is accessible from all Easegress nodes and that you have a consumer ready to process the JSON payloads.

What metrics are available by default when monitoring Easegress?

By default, Easegress emits metrics for HTTP servers (request counts, latency, error rates), pipelines (traffic flow statistics), traffic controllers (routing decisions), and the WAF (refused request counters like waf_total_refused_requests). Each metric includes common fields such as timestamp, hostname, service name, and category, plus object-specific data in the OtherFields payload.

Can I integrate Easegress metrics with Prometheus?

Yes, although Easegress streams metrics to Kafka by default, you can deploy a Kafka-to-Prometheus exporter as a consumer. This service reads JSON metrics from the Kafka topic, parses the OtherFields payload, and exposes the data as Prometheus counters and histograms. Alternatively, you can modify the EaseMonitorMetrics controller to support direct Prometheus scraping, though this requires custom development against the Metricer interface.

How do I add custom metrics to my own Easegress object?

Implement the easemonitor.Metricer interface in your object's Status struct by defining a ToMetrics(service string) []*easemonitor.Metrics method. Return a slice of Metrics structs populated with CommonFields (category, type, resource) and an OtherFields map containing your custom data (e.g., active sessions, cache hit rates). The EaseMonitorMetrics controller will automatically discover and emit these metrics alongside built-in ones.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →