2022-01-25 15:37:43 +01:00
# CCMetric sinks
2021-03-27 13:39:43 +01:00
2022-01-25 15:37:43 +01:00
This folder contains the SinkManager and sink implementations for the cc-metric-collector.
2021-03-27 13:39:43 +01:00
2022-02-04 18:12:24 +01:00
# Available sinks:
- [`stdout` ](./stdoutSink.md ): Print all metrics to `stdout` , `stderr` or a file
- [`http` ](./httpSink.md ): Send metrics to an HTTP server as POST requests
- [`influxdb` ](./influxSink.md ): Send metrics to an [InfluxDB ](https://www.influxdata.com/products/influxdb/ ) database
2022-02-22 16:19:46 +01:00
- [`influxasync` ](./influxAsyncSink.md ): Send metrics to an [InfluxDB ](https://www.influxdata.com/products/influxdb/ ) database with non-blocking write API
2022-02-04 18:12:24 +01:00
- [`nats` ](./natsSink.md ): Publish metrics to the [NATS ](https://nats.io/ ) network overlay system
2022-02-16 18:33:46 +01:00
- [`ganglia` ](./gangliaSink.md ): Publish metrics in the [Ganglia Monitoring System ](http://ganglia.info/ ) using the `gmetric` CLI tool
- [`libganglia` ](./libgangliaSink.md ): Publish metrics in the [Ganglia Monitoring System ](http://ganglia.info/ ) directly using `libganglia.so`
2022-02-25 14:33:20 +01:00
- [`prometeus` ](./prometheusSink.md ): Publish metrics for the [Prometheus Monitoring System ](https://prometheus.io/ )
2022-02-04 18:12:24 +01:00
2022-01-25 15:37:43 +01:00
# Configuration
2021-03-27 13:39:43 +01:00
2022-01-25 15:37:43 +01:00
The configuration file for the sinks is a list of configurations. The `type` field in each specifies which sink to initialize.
2021-11-26 14:10:22 +01:00
```json
2024-07-15 12:41:07 +02:00
{
2022-02-04 18:12:24 +01:00
"mystdout" : {
2022-01-25 15:37:43 +01:00
"type" : "stdout",
2022-11-04 14:52:09 +01:00
"meta_as_tags" : [
"unit"
]
2022-01-25 15:37:43 +01:00
},
2022-02-04 18:12:24 +01:00
"metricstore" : {
2022-01-25 15:37:43 +01:00
"type" : "http",
"host" : "localhost",
"port" : "4123",
"database" : "ccmetric",
"password" : "< jwt token > "
2021-11-26 14:10:22 +01:00
}
2024-07-15 12:41:07 +02:00
}
2022-01-25 15:37:43 +01:00
```
2021-11-26 14:10:22 +01:00
2022-01-25 15:37:43 +01:00
2022-02-04 18:12:24 +01:00
# Contributing own sinks
2022-02-22 16:19:46 +01:00
A sink contains five functions and is derived from the type `sink` :
* `Init(name string, config json.RawMessage) error`
2022-02-04 18:12:24 +01:00
* `Write(point CCMetric) error`
* `Flush() error`
* `Close()`
2022-02-22 16:19:46 +01:00
* `New<Typename>(name string, config json.RawMessage) (Sink, error)` (calls the `Init()` function)
2021-11-26 14:10:22 +01:00
2022-02-04 18:12:24 +01:00
The data structures should be set up in `Init()` like opening a file or server connection. The `Write()` function writes/sends the data. For non-blocking sinks, the `Flush()` method tells the sink to drain its internal buffers. The `Close()` function should tear down anything created in `Init()` .
2022-01-25 15:37:43 +01:00
2022-02-04 18:12:24 +01:00
Finally, the sink needs to be registered in the `sinkManager.go` . There is a list of sinks called `AvailableSinks` which is a map (`sink_type_string` -> `pointer to sink interface` ). Add a new entry with a descriptive name and the new sink.
2022-01-25 15:37:43 +01:00
2022-02-04 18:12:24 +01:00
## Sample sink
2022-01-25 15:37:43 +01:00
2022-02-04 18:12:24 +01:00
```go
package sinks
2022-01-25 15:37:43 +01:00
2022-02-04 18:12:24 +01:00
import (
"encoding/json"
"log"
lp "github.com/ClusterCockpit/cc-metric-collector/internal/ccMetric"
)
2022-01-25 15:37:43 +01:00
2022-02-04 18:12:24 +01:00
type SampleSinkConfig struct {
defaultSinkConfig // defines JSON tags for 'name' and 'meta_as_tags'
2022-01-25 15:37:43 +01:00
}
2021-11-26 14:10:22 +01:00
2022-02-04 18:12:24 +01:00
type SampleSink struct {
sink // declarate 'name' and 'meta_as_tags'
config StdoutSinkConfig // entry point to the SampleSinkConfig
}
2021-11-26 14:10:22 +01:00
2022-02-04 18:12:24 +01:00
// Initialize the sink by giving it a name and reading in the config JSON
2022-02-22 16:19:46 +01:00
func (s *SampleSink) Init(name string, config json.RawMessage) error {
s.name = fmt.Sprintf("SampleSink(%s)", name) // Always specify a name here
2022-02-04 18:12:24 +01:00
// Read in the config JSON
if len(config) > 0 {
err := json.Unmarshal(config, & s.config)
if err != nil {
return err
}
}
return nil
}
2021-11-26 15:56:52 +01:00
2022-02-04 18:12:24 +01:00
// Code to submit a single CCMetric to the sink
func (s *SampleSink) Write(point lp.CCMetric) error {
log.Print(point)
return nil
}
2021-11-26 15:56:52 +01:00
2022-02-04 18:12:24 +01:00
// If the sink uses batched sends internally, you can tell to flush its buffers
func (s *SampleSink) Flush() error {
return nil
}
2021-11-26 15:56:52 +01:00
2022-02-04 18:12:24 +01:00
// Close sink: close network connection, close files, close libraries, ...
func (s *SampleSink) Close() {}
2022-02-22 16:19:46 +01:00
// New function to create a new instance of the sink
func NewSampleSink(name string, config json.RawMessage) (Sink, error) {
s := new(SampleSink)
err := s.Init(name, config)
return s, err
}
2022-11-04 14:52:09 +01:00
```