Code Monkey home page Code Monkey logo

telegraf-rust's Introduction

Telegraf-rust

Telegraf crate Telegraf crate downloads Telegraf documentation

Telegraf-rust is a lightweight client library for general metrics writing using Telegraf. Telegraf is a micro-service provided by InfluxData for making metrics reporting easy for distributed services - see their docs for more information.

This library does not provide querying or other InfluxDB client-library features. This is meant to be lightweight and simple for services to report metrics.

Telegraf-rust supports all socket connection types, such as UDS (unix domain socket):

  • TCP (tcp://)
  • UDP (udp://)
  • UDS Stream (unix://)
  • UDS Datagram (unixgram://)

Install

Add it to your Cargo.toml:

[dependencies]
telegraf = "*"

How to use

Using this library assumes you have a socket listener setup in your Telegraf configuration file. An example TCP connection looks like so:

[[inputs.socket_listener]]
  service_address = "tcp://localhost:8094"

All usage will start by creating a socket connection via a Client. This supports multiple connection protocols - which one you use will be determined by how your Telegraf input.socket_listener configuration is setup.

Once a client is setup there are multiple different ways to write points:

Define structs that represent metrics using the derive macro

use telegraf::*;

let mut client = Client::new("tcp://localhost:8094").unwrap();

#[derive(Metric)]
struct MyMetric {
    field1: i32,
    #[telegraf(tag)]
    tag1: String,
}

let point = MyMetric { field1: 1, tag1: "tag" };
client.write(&point);

By default the measurement name will be the same as the struct. You can override this via derive attributes:

use telegraf::*;

#[derive(Metric)]
#[measurement = "custom_name"]
struct MyMetric {
    field1: i32,
}

As with any Telegraf point, tags are optional but at least one field is required.

Timestamps are optional and can be set via the timestamp attribute:

use telegraf::*;

#[derive(Metric)]
struct MyMetric {
    #[telegraf(timestamp)]
    ts: u64,
    field1: i32,
}

Use the point macro to do ad-hoc metrics

use telegraf::*;

let mut client = Client::new("tcp://localhost:8094").unwrap();

let p = point!("measurement", ("tag1", "tag1Val"), ("field1", "val") ("field2", 10); 100);
client.write_point(&p);

The macro syntax is the following format:

(<measurement>, [(<tagName>, <tagVal>)], [(<fieldName>, <fieldVal>)]; <timestamp>)

Measurement name, tag set, and field set are comma separated. Tag and field tuples are space separated. Timestamp is semicolon separated. The tag set and timestamp are optional.

Manual Point initialization

use telegraf::{Client, Point};

let c = Client::new("tcp://localhost:8094").unwrap();

let p = Point::new(
    String::from("measurement"),
    vec![
        (String::from("tag1"), String::from("tag1value"))
    ],
    vec![
        (String::from("field1"), Box::new(10)),
        (String::from("field2"), Box::new(20.5)),
        (String::from("field3"), Box::new("anything!"))
    ],
    Some(100),
);

c.write_point(p)

Field Data

Any attribute that will be the value of a field must implement the IntoFieldData trait provided by this library.

pub trait IntoFieldData {
    fn field_data(&self) -> FieldData;
}

Out of the box implementations are provided for many common data types, but manual implementation is possible for other data types.

Timestamps

Timestamps are optional. If not present, the Telegraf daemon will set the timestamp using the current time. Timestamps are specified in nanosecond-precision Unix time, therefore u64 must implement the From<T> trait for the field type, if the implementation is not already present:

use telegraf::*;

#[derive(Copy, Clone)]
struct MyType {
    // ...
}

impl From<MyType> for u64 {
    fn from(my_type: MyType) -> Self {
        todo!()
    }
}

#[derive(Metric)]
struct MyMetric {
    #[telegraf(timestamp)]
    ts: MyType,
    field1: i32,
}

More information about timestamps can be found here.

telegraf-rust's People

Contributors

cavivie avatar gordon01 avatar leonardodanelutti avatar maxmindlin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

telegraf-rust's Issues

Empty tag bug

Considering below code:

use telegraf::*;

#[derive(Metric)]
struct MyMetric {
    field: i32,
}

fn main() {
    let mut client = Client::new("udp://127.0.0.1:8080").unwrap();
    let point = MyMetric { field: 12345 };
    client.write(&point);
}

Run the code, and the telegraf agent process will get error:
Unable to parse incoming packet: metric parse error: expected tag at 1:13: "MyMetric, field=12345i"

If I change the packet "MyMetric, field=12345i" to "MyMetric field=12345i", it will work well, should the reason be extra comma?

Please check the telegraf documents: line protocol

point macro format should mirror line protocol format

Subject of the issue

currently the point! macro uses a somewhat custom format that differs from the official line protocol. It should really mirror the line protocol exactly.

Note: backwards compatibility should be preserved if possible.

Allow for optional `Metric` fields

Since InfluxDB's line protocol doesn't allow for explicitly specifying a null value, the only way to accomplish it is by not providing the field.

Currently Metric doesn't let you make one of the fields an Option, so I don't believe there's a way to accomplish this with the library currently.

Implementation of more primitive types for trait IntoFieldData.

Implementation of primitive types for a trait from outside a create is impossible, I need the implementation of IntoFieldData for u16, i16 and i8 and I can't find a way to do so. Is it possible to add more primitive types, in particular i16, i8, u16 and u8.

write point fails with `broken pipe (os error 32)`

Subject of the issue

Describe your issue here.

after some amount of time, a write fails with the OS 32 error mentioned above

Your environment

  • version of Telegraf-rust
    0.6.0

  • version of Rust
    1.68.2 (9eb3afe9e 2023-03-27)

Steps to reproduce

Tell us how to reproduce this issue.

write a bunch of points in a loop for a few hours! :) (check out my public repo... github.com/rabarar/homie-telegraf

Expected behaviour

Tell us what should happen
should be able to drop the connection and reconnect and continue writing...

Actual behaviour

Tell us what happens instead
seems to not recover unless the process is terminated and restarted

Sync+Send for Point

Right now Points are not sendable across threads due to storing field variables as Box<dyn IntoFieldData>.

My use case is that I'd like various modules of my program to sent Points into a channel which then gets read out into the telegraf Client.

If there is an alternative usage pattern for this library for a multi-threaded (/async) program please let me know.

Add tests and releases to CI/CD pipeline

1.) Tests should be ran against any PR before merged to master, along with against master.
2.) Add an action for incrementing the package version and releasing to crates.io when a tag is cut.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.