InfluxDB.Client 4.7.0-dev.8557

This is a prerelease version of InfluxDB.Client.
There is a newer version of this package available.
See the version list below for details.
dotnet add package InfluxDB.Client --version 4.7.0-dev.8557
                    
NuGet\Install-Package InfluxDB.Client -Version 4.7.0-dev.8557
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="InfluxDB.Client" Version="4.7.0-dev.8557" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="InfluxDB.Client" Version="4.7.0-dev.8557" />
                    
Directory.Packages.props
<PackageReference Include="InfluxDB.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add InfluxDB.Client --version 4.7.0-dev.8557
                    
#r "nuget: InfluxDB.Client, 4.7.0-dev.8557"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=InfluxDB.Client&version=4.7.0-dev.8557&prerelease
                    
Install InfluxDB.Client as a Cake Addin
#tool nuget:?package=InfluxDB.Client&version=4.7.0-dev.8557&prerelease
                    
Install InfluxDB.Client as a Cake Tool

InfluxDB.Client

CircleCI

The reference client that allows query, write and management (bucket, organization, users) for the InfluxDB 2.x.

Documentation

This section contains links to the client library documentation.

Features

Queries

For querying data we use QueryApi that allow perform asynchronous, streaming, synchronous and also use raw query response.

Asynchronous Query

The asynchronous query is not intended for large query results because the Flux response can be potentially unbound.

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class AsynchronousQuery
    {
        private static readonly string Token = "";

        public static async Task Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
            
            var queryApi = influxDBClient.GetQueryApi();

            //
            // QueryData
            //
            var tables = await queryApi.QueryAsync(flux, "org_id");
            tables.ForEach(table =>
            {
                table.Records.ForEach(record =>
                {
                    Console.WriteLine($"{record.GetTime()}: {record.GetValueByKey("_value")}");
                });
            });

            influxDBClient.Dispose();
        }        
    }
}

The asynchronous query offers a possibility map FluxRecords to POCO:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Core;

namespace Examples
{
    public static class AsynchronousQuery
    {
        private static readonly string Token = "";

        public static async Task Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
            
            var queryApi = influxDBClient.GetQueryApi();

            //
            // QueryData
            //
            var temperatures = await queryApi.QueryAsync<Temperature>(flux, "org_id");
            temperatures.ForEach(temperature =>
            {
                Console.WriteLine($"{temperature.Location}: {temperature.Value} at {temperature.Time}");
            });

            influxDBClient.Dispose();
        }  
        
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
    }
}

Streaming Query

The Streaming query offers possibility to process unbound query and allow user to handle exceptions, stop receiving more results and notify that all data arrived.

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class StreamingQuery
    {
        private static readonly string Token = "";

        public static async Task Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";

            var queryApi = influxDBClient.GetQueryApi();

            //
            // QueryData
            //
            await queryApi.QueryAsync(flux, record =>
            {
                //
                // The callback to consume a FluxRecord.
                //
                Console.WriteLine($"{record.GetTime()}: {record.GetValueByKey("_value")}");
            }, exception =>
            {
                //
                // The callback to consume any error notification.
                //
                Console.WriteLine($"Error occurred: {exception.Message}");
            }, () =>
            {
                //
                // The callback to consume a notification about successfully end of stream.
                //
                Console.WriteLine("Query completed");
            }, "org_id");

            influxDBClient.Dispose();
        }
    }
}

And there is also a possibility map FluxRecords to POCO:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Core;

namespace Examples
{
    public static class StreamingQuery
    {
        private static readonly string Token = "";

        public static async Task Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
            
            var queryApi = influxDBClient.GetQueryApi();

            //
            // QueryData
            //
            await queryApi.QueryAsync<Temperature>(flux, temperature =>
            {
                //
                // The callback to consume a FluxRecord mapped to POCO.
                //
                Console.WriteLine($"{temperature.Location}: {temperature.Value} at {temperature.Time}");
            }, org: "org_id");

            influxDBClient.Dispose();
        }  
        
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
    }
}

Raw Query

The Raw query allows direct processing original CSV response:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class RawQuery
    {
        private static readonly string Token = "";

        public static async Task Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";

            var queryApi = influxDBClient.GetQueryApi();

            //
            // QueryData
            //
            var csv = await queryApi.QueryRawAsync(flux, org: "org_id");
            
            Console.WriteLine($"CSV response: {csv}");

            influxDBClient.Dispose();
        }
    }
}

The Streaming version allows processing line by line:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class RawQueryAsynchronous
    {
        private static readonly string Token = "";

        public static async Task Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";

            var queryApi = influxDBClient.GetQueryApi();

            //
            // QueryData
            //
            await queryApi.QueryRawAsync(flux, line =>
            {
                //
                // The callback to consume a line of CSV response
                //
                Console.WriteLine($"Response: {line}");
            }, org: "org_id");

            influxDBClient.Dispose();
        }
    }
}

Synchronous query

The synchronous query is not intended for large query results because the response can be potentially unbound.

using System;
using InfluxDB.Client;

namespace Examples
{
    public static class SynchronousQuery
    {
        public static void Main(string[] args)
        {
            using var client = InfluxDBClientFactory.Create("http://localhost:9999", "my-token");

            const string query = "from(bucket:\"my-bucket\") |> range(start: 0)";
           
            //
            // QueryData
            //
            var queryApi = client.GetQueryApiSync();
            var tables = queryApi.QuerySync(query, "my-org");
            
            //
            // Process results
            //
            tables.ForEach(table =>
            {
                table.Records.ForEach(record =>
                {
                    Console.WriteLine($"{record.GetTime()}: {record.GetValueByKey("_value")}");
                });
            });
        }
    }
}

Writes

For writing data we use WriteApi or WriteApiAsync which is simplified version of WriteApi without batching support.

WriteApi supports:

  1. writing data using InfluxDB Line Protocol, Data Point, POCO
  2. use batching for writes
  3. produces events that allow user to be notified and react to this events
    • WriteSuccessEvent - published when arrived the success response from server
    • WriteErrorEvent - published when occurs a unhandled exception from server
    • WriteRetriableErrorEvent - published when occurs a retriable error from server
    • WriteRuntimeExceptionEvent - published when occurs a runtime exception in background batch processing
  4. use GZIP compression for data

The writes are processed in batches which are configurable by WriteOptions:

Property Description Default Value
BatchSize the number of data point to collect in batch 1000
FlushInterval the number of milliseconds before the batch is written 1000
JitterInterval the number of milliseconds to increase the batch flush interval by a random amount 0
RetryInterval the number of milliseconds to retry unsuccessful write. The retry interval is used when the InfluxDB server does not specify "Retry-After" header. 5000
MaxRetries the number of max retries when write fails 3
MaxRetryDelay the maximum delay between each retry attempt in milliseconds 125_000
ExponentialBase the base for the exponential retry delay, the next delay is computed using random exponential backoff as a random value within the interval retryInterval * exponentialBase^(attempts-1) and retryInterval * exponentialBase^(attempts). Example for retryInterval=5_000, exponentialBase=2, maxRetryDelay=125_000, maxRetries=5 Retry delays are random distributed values within the ranges of [5_000-10_000, 10_000-20_000, 20_000-40_000, 40_000-80_000, 80_000-125_000] 2

Writing data

By POCO

Write Measurement into specified bucket:

using System;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Core;

namespace Examples
{
    public static class WritePoco
    {
        private static readonly string Token = "";

        public static void Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = influxDBClient.GetWriteApi())
            {
                //
                // Write by POCO
                //
                var temperature = new Temperature {Location = "south", Value = 62D, Time = DateTime.UtcNow};

                writeApi.WriteMeasurement(temperature, WritePrecision.Ns, "bucket_name", "org_id");
            }
            
            influxDBClient.Dispose();
        }
        
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
    }
}
By Data Point

Write Data point into specified bucket:

using System;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class WriteDataPoint
    {
        private static readonly string Token = "";

        public static void Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = influxDBClient.GetWriteApi())
            {
                //
                // Write by Data Point
                
                var point = PointData.Measurement("temperature")
                    .Tag("location", "west")
                    .Field("value", 55D)
                    .Timestamp(DateTime.UtcNow.AddSeconds(-10), WritePrecision.Ns);
                
                writeApi.WritePoint(point, "bucket_name", "org_id");
            }
            
            influxDBClient.Dispose();
        }
    }
}

DataPoint Builder Immutability: The builder is immutable therefore won't have side effect when using for building multiple point with single builder.

using System;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class WriteDataPoint
    {
        private static readonly string Token = "";

        public static void Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = influxDBClient.GetWriteApi())
            {
                //
                // Write by Data Point
                
                var builder = PointData.Measurement("temperature")
                    .Tag("location", "west");
                
                var pointA = builder
                    .Field("value", 55D)
                    .Timestamp(DateTime.UtcNow.AddSeconds(-10), WritePrecision.Ns);
                
                writeApi.WritePoint(pointA, "bucket_name", "org_id");
                
                var pointB = builder
                    .Field("age", 32)
                    .Timestamp(DateTime.UtcNow, WritePrecision.Ns);
                
                writeApi.WritePoint(pointB, "bucket_name", "org_id");
            }
            
            influxDBClient.Dispose();
        }
    }
}
By LineProtocol

Write Line Protocol record into specified bucket:

using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;

namespace Examples
{
    public static class WriteLineProtocol
    {
        private static readonly string Token = "";

        public static void Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = influxDBClient.GetWriteApi())
            {
                //
                //
                // Write by LineProtocol
                //
                writeApi.WriteRecord("temperature,location=north value=60.0", WritePrecision.Ns,"bucket_name", "org_id");
            }
            
            influxDBClient.Dispose();
        }
    }
}
Using WriteApiAsync
using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Core;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class WriteApiAsyncExample
    {   
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
        
        public static async Task Main(string[] args)
        {
            var influxDbClient = InfluxDBClientFactory.Create("http://localhost:8086", 
                            "my-user", "my-password".ToCharArray());

            //
            // Write Data
            //
            var writeApiAsync = influxDbClient.GetWriteApiAsync();

            //
            //
            // Write by LineProtocol
            //
            await writeApiAsync.WriteRecordAsync("temperature,location=north value=60.0", WritePrecision.Ns,
                "my-bucket", "my-org");

            //
            //
            // Write by Data Point
            //               
            var point = PointData.Measurement("temperature")
                            .Tag("location", "west")
                            .Field("value", 55D)
                            .Timestamp(DateTime.UtcNow.AddSeconds(-10), WritePrecision.Ns);

            await writeApiAsync.WritePointAsync(point, "my-bucket", "my-org");

            //
            // Write by POCO
            //
            var temperature = new Temperature {Location = "south", Value = 62D, Time = DateTime.UtcNow};

            await writeApiAsync.WriteMeasurementAsync(temperature, WritePrecision.Ns, "my-bucket", "my-org");

            //
            // Check written data
            //
            var tables = await influxDbClient.GetQueryApi()
                            .QueryAsync("from(bucket:\"my-bucket\") |> range(start: 0)", "my-org");
            
            tables.ForEach(table =>
            {
                var fluxRecords = table.Records;
                fluxRecords.ForEach(record =>
                {
                    Console.WriteLine($"{record.GetTime()}: {record.GetValue()}");
                });
            });
            
            influxDbClient.Dispose();
        }
    }
}
Default Tags

Sometimes is useful to store same information in every measurement e.g. hostname, location, customer. The client is able to use static value, app settings or env variable as a tag value.

The expressions:

  • California Miner - static value
  • ${version} - application settings
  • ${env.hostname} - environment property
Via Configuration file

In a configuration file you are able to specify default tags by tags element.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="influx2" type="InfluxDB.Client.Configurations.Influx2, InfluxDB.Client" />
    </configSections>
    <appSettings>
        <add key="SensorVersion" value="v1.00"/>
    </appSettings>
    <influx2 url="http://localhost:8086"
             org="my-org"
             bucket="my-bucket"
             token="my-token"
             logLevel="BODY"
             timeout="10s">
        <tags>
            <tag name="id" value="132-987-655"/>
            <tag name="customer" value="California Miner"/>
            <tag name="hostname" value="${env.Hostname}"/>
            <tag name="sensor-version" value="${SensorVersion}"/>
        </tags>
    </influx2>
</configuration>
Via API
var options = new InfluxDBClientOptions.Builder()
    .Url(url)
    .AuthenticateToken(token)
    .AddDefaultTag("id", "132-987-655")
    .AddDefaultTag("customer", "California Miner")
    .AddDefaultTag("hostname", "${env.Hostname}")
    .AddDefaultTag("sensor-version", "${SensorVersion}")
    .Build()    

Both of configurations will produce the Line protocol:

mine-sensor,id=132-987-655,customer="California Miner",hostname=example.com,sensor-version=v1.00 altitude=10

Handle the Events

Events that can be handle by WriteAPI EventHandler are:

  • WriteSuccessEvent - for success response from server
  • WriteErrorEvent - for unhandled exception from server
  • WriteRetriableErrorEvent - for retriable error from server
  • WriteRuntimeExceptionEvent - for runtime exception in background batch processing

Number of events depends on number of data points to collect in batch. The batch size is configured by BatchSize option (default size is 1000) - in case of one data point, event is handled for each point, independently on used writing method (even for mass writing of data like WriteMeasurements, WritePoints and WriteRecords).

Events can be handled by register writeApi.EventHandler or by creating custom EventListener:

Register EventHandler
writeApi.EventHandler += (sender, eventArgs) =>
{
    switch (eventArgs)
    {
        case WriteSuccessEvent successEvent:
            string data = @event.LineProtocol;
            //
            // handle success response from server
            // Console.WriteLine($"{data}");
            //
            break;
        case WriteErrorEvent error:
            string data = @error.LineProtocol;
            string errorMessage = @error.Exception.Message;
            //
            // handle unhandled exception from server
            //
            // Console.WriteLine($"{data}");
            // throw new Exception(errorMessage);
            //
            break;
        case WriteRetriableErrorEvent error:
            string data = @error.LineProtocol;
            string errorMessage = @error.Exception.Message;
            //
            // handle retrievable error from server
            //
            // Console.WriteLine($"{data}");
            // throw new Exception(errorMessage);
            //
            break;
        case WriteRuntimeExceptionEvent error:
            string errorMessage = @error.Exception.Message;
            //
            // handle runtime exception in background batch processing
            // throw new Exception(errorMessage);
            //
            break;
    }
};

//
// Write by LineProtocol
//
writeApi.WriteRecord("influxPoint,writeType=lineProtocol value=11.11" +
    $" {DateTime.UtcNow.Subtract(EpochStart).Ticks * 100}", WritePrecision.Ns, "my-bucket", "my-org");
Custom EventListener

Advantage of using custom Event Listener is possibility of waiting on handled event between different writings - for more info see EventListener.

Delete Data

Delete data from specified bucket:

using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;

namespace Examples
{
    public static class WriteLineProtocol
    {
        private static readonly string Token = "";

        public static void Main(string[] args)
        {
            var influxDBClient = InfluxDBClientFactory.Create("http://localhost:8086", Token);

            //
            // Delete data
            //
            await influxDB.GetDeleteApi().Delete(DateTime.UtcNow.AddMinutes(-1), DateTime.Now, "", "bucket", "org");
            
            influxDBClient.Dispose();
        }
    }
}

Management API

The client has following management API:

API endpoint Description Implementation
/api/v2/authorizations Managing authorization data AuthorizationsApi
/api/v2/buckets Managing bucket data BucketsApi
/api/v2/orgs Managing organization data OrganizationsApi
/api/v2/users Managing user data UsersApi
/api/v2/sources Managing sources SourcesApi
/api/v2/tasks Managing one-off and recurring tasks TasksApi
/api/v2/scrapers Managing ScraperTarget data ScraperTargetsApi
/api/v2/labels Managing resource labels LabelsApi
/api/v2/telegrafs Managing telegraf config data TelegrafsApi
/api/v2/setup Managing onboarding setup InfluxDBClient#OnBoarding()
/ready Get the readiness of a instance at startup InfluxDBClient#Ready()
/health Get the health of an instance anytime during execution InfluxDBClient#Health()

The following example demonstrates how to use a InfluxDB 2.x Management API. For further information see endpoints implementation.

using System;
using System.Collections.Generic;
using System.Linq;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using Task = System.Threading.Tasks.Task;

namespace Examples
{
    public static class ManagementExample
    {
        public static async Task Main(string[] args)
        {
            const string url = "http://localhost:8086";
            const string token = "my-token";
            const string org = "my-org";
            
            using var client = InfluxDBClientFactory.Create(url, token);

            // Find ID of Organization with specified name (PermissionAPI requires ID of Organization).
            var orgId = (await client.GetOrganizationsApi().FindOrganizationsAsync(org: org)).First().Id;

            //
            // Create bucket "iot_bucket" with data retention set to 3,600 seconds
            //
            var retention = new BucketRetentionRules(BucketRetentionRules.TypeEnum.Expire, 3600);

            var bucket = await client.GetBucketsApi().CreateBucketAsync("iot_bucket", retention, orgId);

            //
            // Create access token to "iot_bucket"
            //
            var resource = new PermissionResource(PermissionResource.TypeBuckets, bucket.Id, null,
                orgId);

            // Read permission
            var read = new Permission(Permission.ActionEnum.Read, resource);

            // Write permission
            var write = new Permission(Permission.ActionEnum.Write, resource);

            var authorization = await client.GetAuthorizationsApi()
                .CreateAuthorizationAsync(orgId, new List<Permission> { read, write });

            //
            // Created token that can be use for writes to "iot_bucket"
            //
            Console.WriteLine($"Authorized token to write into iot_bucket: {authorization.Token}");
        }
    }
}

If there is no API implementation for particular service you could create the service by:

var dbrpService = _client.CreateService<DBRPsService>(typeof(DBRPsService));

Advanced Usage

Monitoring & Alerting

The example below show how to create a check for monitoring a stock price. A Slack notification is created if the price is lesser than 35.

Create Threshold Check

The Check set status to Critical if the current value for a stock measurement is lesser than 35.

var org = ...;

var query = "from(bucket: \"my-bucket\") "
        + "|> range(start: v.timeRangeStart, stop: v.timeRangeStop)  "
        + "|> filter(fn: (r) => r._measurement == \"stock\")  "
        + "|> filter(fn: (r) => r.company == \"zyz\")  "
        + "|> aggregateWindow(every: 5s, fn: mean)  "
        + "|> filter(fn: (r) => r._field == \"current\")  "
        + "|> yield(name: \"mean\")";

var threshold = new LesserThreshold(value: 35F, level: CheckStatusLevel.CRIT,
                type: LesserThreshold.TypeEnum.Lesser);

var message = "The Stock price for XYZ is on: ${ r._level } level!";

await Client
    .GetChecksApi()
    .CreateThresholdCheckAsync("XYZ Stock value", query, "5s", message, threshold, org.Id);
Create Slack Notification endpoint
var url = "https://hooks.slack.com/services/x/y/z"; 

var endpoint = await Client
    .GetNotificationEndpointsApi()
    .CreateSlackEndpointAsync("Slack Endpoint", url, org.Id);
Create Notification Rule
await Client
    .GetNotificationRulesApi()
    .CreateSlackRuleAsync("Critical status to Slack", "10s", "${ r._message }", RuleStatusLevel.CRIT, endpoint, org.Id);

Custom mapping of DomainObject to/from InfluxDB

The default mapper uses Column attributes to define how the DomainObject will be mapped to and from the InfluxDB. The our APIs also allow to specify custom mapper. For more information see following example:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Core.Flux.Domain;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class CustomDomainMapping
    {
        /// <summary>
        /// Define Domain Object
        /// </summary>
        private class Sensor
        {
            /// <summary>
            /// Type of sensor.
            /// </summary>
            public String Type { get; set; }
            
            /// <summary>
            /// Version of sensor.
            /// </summary>
            public String Version { get; set; }

            /// <summary>
            /// Measured value.
            /// </summary>
            public double Value { get; set; }

            public DateTimeOffset Timestamp { get; set; }

            public override string ToString()
            {
                return $"{Timestamp:MM/dd/yyyy hh:mm:ss.fff tt} {Type}, {Version} value: {Value}";
            }
        }

        /// <summary>
        /// Define Custom Domain Object Converter
        /// </summary>
        private class DomainEntityConverter : IDomainObjectMapper
        {
            /// <summary>
            /// Convert to DomainObject.
            /// </summary>
            public object ConvertToEntity(FluxRecord fluxRecord, Type type)
            {
                if (type != typeof(Sensor))
                {
                    throw new NotSupportedException($"This converter doesn't supports: {type}");
                }

                var customEntity = new Sensor
                {
                    Type = Convert.ToString(fluxRecord.GetValueByKey("type")),
                    Version = Convert.ToString(fluxRecord.GetValueByKey("version")),
                    Value = Convert.ToDouble(fluxRecord.GetValueByKey("data")),
                    Timestamp = fluxRecord.GetTime().GetValueOrDefault().ToDateTimeUtc(),
                };
                
                return Convert.ChangeType(customEntity, type);
            }
            
            /// <summary>
            /// Convert to DomainObject.
            /// </summary>
            public T ConvertToEntity<T>(FluxRecord fluxRecord)
            {
                return (T)ConvertToEntity(fluxRecord, typeof(T));
            }

            /// <summary>
            /// Convert to Point
            /// </summary>
            public PointData ConvertToPointData<T>(T entity, WritePrecision precision)
            {
                if (!(entity is Sensor sensor))
                {
                    throw new NotSupportedException($"This converter doesn't supports: {entity}");
                }

                var point = PointData
                    .Measurement("sensor")
                    .Tag("type", sensor.Type)
                    .Tag("version", sensor.Version)
                    .Field("data", sensor.Value)
                    .Timestamp(sensor.Timestamp, precision);

                return point;
            }
        }

        public static async Task Main(string[] args)
        {
            const string host = "http://localhost:9999";
            const string token = "my-token";
            const string bucket = "my-bucket";
            const string organization = "my-org";
            var options = new InfluxDBClientOptions.Builder()
                .Url(host)
                .AuthenticateToken(token.ToCharArray())
                .Org(organization)
                .Bucket(bucket)
                .Build();

            var converter = new DomainEntityConverter();
            var client = InfluxDBClientFactory.Create(options);

            //
            // Prepare data to write
            //
            var time = new DateTimeOffset(2020, 11, 15, 8, 20, 15,
                new TimeSpan(3, 0, 0));

            var entity1 = new Sensor
            {
                Timestamp = time,
                Type = "temperature",
                Version = "v0.0.2",
                Value = 15
            };
            var entity2 = new Sensor
            {
                Timestamp = time.AddHours(1),
                Type = "temperature",
                Version = "v0.0.2",
                Value = 15
            };
            var entity3 = new Sensor
            {
                Timestamp = time.AddHours(2),
                Type = "humidity",
                Version = "v0.13",
                Value = 74
            };
            var entity4 = new Sensor
            {
                Timestamp = time.AddHours(3),
                Type = "humidity",
                Version = "v0.13",
                Value = 82
            };

            //
            // Write data
            //
            await client.GetWriteApiAsync(converter)
                .WriteMeasurementsAsync(new []{entity1, entity2, entity3, entity4}, WritePrecision.S);

            //
            // Query Data to Domain object
            //
            var queryApi = client.GetQueryApiSync(converter);

            //
            // Select ALL
            //
            var query = $"from(bucket:\"{bucket}\") " +
                        "|> range(start: 0) " +
                        "|> filter(fn: (r) => r[\"_measurement\"] == \"sensor\")" +
                        "|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")";
           
            var sensors = queryApi.QuerySync<Sensor>(query);
            //
            // Print result
            //
            sensors.ForEach(it => Console.WriteLine(it.ToString()));

            client.Dispose();
        }
    }
}

Client configuration file

A client can be configured via App.config file.

The following options are supported:

Property name default description
Url - the url to connect to InfluxDB
Org - default destination organization for writes and queries
Bucket - default destination bucket for writes
Token - the token to use for the authorization
LogLevel NONE rest client verbosity level
Timeout 10000 ms The timespan to wait before the HTTP request times out
AllowHttpRedirects false Configure automatically following HTTP 3xx redirects
VerifySsl true Ignore Certificate Validation Errors when false

The Timeout supports ms, s and m as unit. Default is milliseconds.

Configuration example
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="influx2" type="InfluxDB.Client.Configurations.Influx2, InfluxDB.Client" />
    </configSections>

    <influx2 url="http://localhost:8086"
             org="my-org"
             bucket="my-bucket"
             token="my-token"
             logLevel="BODY"
             timeout="10s">
    </influx2>
</configuration>

and then:

var influxDBClient = InfluxDBClientFactory.Create();

Client connection string

A client can be constructed using a connection string that can contain the InfluxDBClientOptions parameters encoded into the URL.

var influxDBClient = InfluxDBClientFactory
            .Create("http://localhost:8086?timeout=5000&logLevel=BASIC")

The following options are supported:

Property name default description
org - default destination organization for writes and queries
bucket - default destination bucket for writes
token - the token to use for the authorization
logLevel NONE rest client verbosity level
timeout 10000 ms The timespan to wait before the HTTP request times out.
allowHttpRedirects false Configure automatically following HTTP 3xx redirects
verifySsl true Ignore Certificate Validation Errors when false

The timeout supports ms, s and m as unit. Default is milliseconds.

Gzip support

InfluxDBClient does not enable gzip compress for http requests by default. If you want to enable gzip to reduce transfer data's size, you can call:

influxDBClient.EnableGzip();

How to use WebProxy

The WebProxy could be configured via InfluxDBClientOptions.Builder:

var options = new InfluxDBClientOptions.Builder()
    .Url("http://localhost:8086")
    .AuthenticateToken("my-token".ToCharArray())
    .Proxy(new WebProxy("http://proxyserver:80/", true))
    .Build();

var client = InfluxDBClientFactory.Create(options);

Proxy and redirects configuration

You can configure the client to tunnel requests through an HTTP proxy. To configure the proxy use Proxy configuration option:

var options = new InfluxDBClientOptions.Builder()
   .Url("http://localhost:8086")
   .AuthenticateToken("my-token")
   .Proxy(new WebProxy("http://proxyserver:80/", true))
   .Build();

using var client = InfluxDBClientFactory.Create(options);

Client automatically doesn't follows HTTP redirects. You can enable redirects by AllowRedirects configuration option:

var options = new InfluxDBClientOptions.Builder()
    .Url("http://localhost:8086")
    .AllowRedirects(true)
    .Build();

using var client = InfluxDBClientFactory.Create(options);

⚠️ Due to a security reason Authorization header is not forwarded when redirect leads to a different domain. You can create custom Authenticator which change this behaviour - see more.

Log HTTP Request and Response

The Requests and Responses can be logged by changing the LogLevel. LogLevel values are None, Basic, Headers, Body. Note that applying the Body LogLevel will disable chunking while streaming and will load the whole response into memory.

influxDBClient.SetLogLevel(LogLevel.Body)
Check the server status and version

Server availability can be checked using the influxDBClient.PingAsync() endpoint.

Version

The latest package for .NET CLI:

dotnet add package InfluxDB.Client

Or when using with Package Manager:

Install-Package InfluxDB.Client
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (31)

Showing the top 5 NuGet packages that depend on InfluxDB.Client:

Package Downloads
InfluxDB.Client.Linq

The library supports querying InfluxDB 2.x by LINQ expressions.

NBomber.Sinks.InfluxDB

NBomber sink that writes stats data to InfluxDB.

Serilog.Sinks.InfluxDB.Syslog

InfluxDB sink for Serilog with .NET standard 2.0 using syslog format for Influx 2.X

AspNetCore.HealthChecks.InfluxDB

HealthChecks.InfluxDB is the health check package for InfluxDB.

OpenTelemetry.Exporter.InfluxDB

An OpenTelemetry .NET exporter that exports to InfluxDB.

GitHub repositories (8)

Showing the top 8 popular GitHub repositories that depend on InfluxDB.Client:

Repository Stars
Xabaril/AspNetCore.Diagnostics.HealthChecks
Enterprise HealthChecks for ASP.NET Core Diagnostics Package
testcontainers/testcontainers-dotnet
A library to support tests with throwaway instances of Docker containers for all compatible .NET Standard versions.
IoTSharp/IoTSharp
IoTSharp is an open-source IoT platform for data collection, processing, visualization, and device management.
melanchall/drywetmidi
Swiss knife for everything MIDI related
ConcreteMC/Alex
A Minecraft client written in C# aimed at compatibility with MC:Java & MC:Bedrock
open-telemetry/opentelemetry-dotnet-contrib
This repository contains set of components extending functionality of the OpenTelemetry .NET SDK. Instrumentation libraries, exporters, and other components can find their home here.
nickbabcock/OhmGraphite
Expose hardware sensor data to Graphite / InfluxDB / Prometheus / Postgres / Timescaledb
RapidScada/scada-v6
Contains Rapid SCADA 6 source code
Version Downloads Last updated
4.19.0-dev.15190 1,805 12/5/2024
4.19.0-dev.15189 65 12/5/2024
4.19.0-dev.15188 60 12/5/2024
4.19.0-dev.15178 58 12/5/2024
4.19.0-dev.15177 62 12/5/2024
4.19.0-dev.14906 1,815 10/2/2024
4.19.0-dev.14897 68 10/2/2024
4.19.0-dev.14896 68 10/2/2024
4.19.0-dev.14895 100 10/2/2024
4.19.0-dev.14811 274 9/13/2024
4.18.0 434,834 9/13/2024
4.18.0-dev.14769 141 9/4/2024
4.18.0-dev.14743 85 9/3/2024
4.18.0-dev.14694 80 9/3/2024
4.18.0-dev.14693 67 9/3/2024
4.18.0-dev.14692 70 9/3/2024
4.18.0-dev.14618 90 9/2/2024
4.18.0-dev.14609 72 9/2/2024
4.18.0-dev.14592 66 9/2/2024
4.18.0-dev.14446 811 8/19/2024
4.18.0-dev.14414 356 8/12/2024
4.17.0 111,788 8/12/2024
4.17.0-dev.headers.read.1 221 7/22/2024
4.17.0-dev.14350 57 8/5/2024
4.17.0-dev.14333 58 8/5/2024
4.17.0-dev.14300 56 8/5/2024
4.17.0-dev.14291 54 8/5/2024
4.17.0-dev.14189 106 7/23/2024
4.17.0-dev.14179 79 7/22/2024
4.17.0-dev.14101 280 7/1/2024
4.17.0-dev.14100 74 7/1/2024
4.17.0-dev.14044 119 6/24/2024
4.16.0 138,194 6/24/2024
4.16.0-dev.13990 3,529 6/3/2024
4.16.0-dev.13973 77 6/3/2024
4.16.0-dev.13972 70 6/3/2024
4.16.0-dev.13963 86 6/3/2024
4.16.0-dev.13962 75 6/3/2024
4.16.0-dev.13881 74 6/3/2024
4.16.0-dev.13775 186 5/17/2024
4.16.0-dev.13702 86 5/17/2024
4.15.0 69,691 5/17/2024
4.15.0-dev.13674 95 5/14/2024
4.15.0-dev.13567 1,500 4/2/2024
4.15.0-dev.13558 76 4/2/2024
4.15.0-dev.13525 79 4/2/2024
4.15.0-dev.13524 78 4/2/2024
4.15.0-dev.13433 286 3/7/2024
4.15.0-dev.13432 81 3/7/2024
4.15.0-dev.13407 111 3/7/2024
4.15.0-dev.13390 79 3/7/2024
4.15.0-dev.13388 79 3/7/2024
4.15.0-dev.13282 264 3/6/2024
4.15.0-dev.13257 89 3/6/2024
4.15.0-dev.13113 1,149 2/1/2024
4.15.0-dev.13104 82 2/1/2024
4.15.0-dev.13081 83 2/1/2024
4.15.0-dev.13040 145 2/1/2024
4.15.0-dev.13039 83 2/1/2024
4.15.0-dev.12863 2,087 1/8/2024
4.15.0-dev.12846 91 1/8/2024
4.15.0-dev.12837 89 1/8/2024
4.15.0-dev.12726 2,744 12/1/2023
4.15.0-dev.12725 98 12/1/2023
4.15.0-dev.12724 94 12/1/2023
4.15.0-dev.12691 97 12/1/2023
4.15.0-dev.12658 105 12/1/2023
4.15.0-dev.12649 91 12/1/2023
4.15.0-dev.12624 92 12/1/2023
4.15.0-dev.12471 1,069 11/7/2023
4.15.0-dev.12462 94 11/7/2023
4.14.0 538,905 11/7/2023
4.14.0-dev.12437 94 11/7/2023
4.14.0-dev.12343 139 11/2/2023
4.14.0-dev.12310 96 11/2/2023
4.14.0-dev.12284 367 11/1/2023
4.14.0-dev.12235 114 11/1/2023
4.14.0-dev.12226 94 11/1/2023
4.14.0-dev.11972 5,667 8/8/2023
4.14.0-dev.11915 165 7/31/2023
4.14.0-dev.11879 181 7/28/2023
4.13.0 316,520 7/28/2023
4.13.0-dev.11854 119 7/28/2023
4.13.0-dev.11814 379 7/21/2023
4.13.0-dev.11771 166 7/19/2023
4.13.0-dev.11770 126 7/19/2023
4.13.0-dev.11728 147 7/18/2023
4.13.0-dev.11686 222 7/17/2023
4.13.0-dev.11685 112 7/17/2023
4.13.0-dev.11676 124 7/17/2023
4.13.0-dev.11479 2,091 6/27/2023
4.13.0-dev.11478 122 6/27/2023
4.13.0-dev.11477 122 6/27/2023
4.13.0-dev.11396 481 6/19/2023
4.13.0-dev.11395 112 6/19/2023
4.13.0-dev.11342 371 6/15/2023
4.13.0-dev.11330 309 6/12/2023
4.13.0-dev.11305 128 6/12/2023
4.13.0-dev.11296 125 6/12/2023
4.13.0-dev.11217 397 6/6/2023
4.13.0-dev.11089 316 5/30/2023
4.13.0-dev.11064 151 5/30/2023
4.13.0-dev.10998 187 5/29/2023
4.13.0-dev.10989 142 5/29/2023
4.13.0-dev.10871 909 5/8/2023
4.13.0-dev.10870 120 5/8/2023
4.13.0-dev.10819 300 4/28/2023
4.12.0 192,602 4/28/2023
4.12.0-dev.10777 160 4/27/2023
4.12.0-dev.10768 143 4/27/2023
4.12.0-dev.10759 134 4/27/2023
4.12.0-dev.10742 119 4/27/2023
4.12.0-dev.10685 128 4/27/2023
4.12.0-dev.10684 131 4/27/2023
4.12.0-dev.10643 139 4/27/2023
4.12.0-dev.10642 123 4/27/2023
4.12.0-dev.10569 124 4/27/2023
4.12.0-dev.10193 1,780 2/23/2023
4.11.0 122,717 2/23/2023
4.11.0-dev.10176 208 2/23/2023
4.11.0-dev.10059 3,193 1/26/2023
4.10.0 74,468 1/26/2023
4.10.0-dev.10033 172 1/25/2023
4.10.0-dev.10032 149 1/25/2023
4.10.0-dev.10031 162 1/25/2023
4.10.0-dev.9936 3,692 12/26/2022
4.10.0-dev.9935 170 12/26/2022
4.10.0-dev.9881 209 12/21/2022
4.10.0-dev.9880 149 12/21/2022
4.10.0-dev.9818 640 12/16/2022
4.10.0-dev.9773 331 12/12/2022
4.10.0-dev.9756 146 12/12/2022
4.10.0-dev.9693 394 12/6/2022
4.9.0 229,081 12/6/2022
4.9.0-dev.9684 141 12/6/2022
4.9.0-dev.9666 149 12/6/2022
4.9.0-dev.9617 167 12/6/2022
4.9.0-dev.9478 233 12/5/2022
4.9.0-dev.9469 168 12/5/2022
4.9.0-dev.9444 132 12/5/2022
4.9.0-dev.9411 151 12/5/2022
4.9.0-dev.9350 189 12/1/2022
4.8.0 5,898 12/1/2022
4.8.0-dev.9324 234 11/30/2022
4.8.0-dev.9232 211 11/28/2022
4.8.0-dev.9223 150 11/28/2022
4.8.0-dev.9222 147 11/28/2022
4.8.0-dev.9117 435 11/21/2022
4.8.0-dev.9108 151 11/21/2022
4.8.0-dev.9099 150 11/21/2022
4.8.0-dev.9029 224 11/16/2022
4.8.0-dev.8971 156 11/15/2022
4.8.0-dev.8961 160 11/14/2022
4.8.0-dev.8928 165 11/14/2022
4.8.0-dev.8899 159 11/14/2022
4.8.0-dev.8898 171 11/14/2022
4.8.0-dev.8839 161 11/14/2022
4.8.0-dev.8740 273 11/7/2022
4.8.0-dev.8725 154 11/7/2022
4.8.0-dev.8648 391 11/3/2022
4.7.0 109,409 11/3/2022
4.7.0-dev.8625 297 11/2/2022
4.7.0-dev.8594 312 10/31/2022
4.7.0-dev.8579 149 10/31/2022
4.7.0-dev.8557 138 10/31/2022
4.7.0-dev.8540 158 10/31/2022
4.7.0-dev.8518 149 10/31/2022
4.7.0-dev.8517 149 10/31/2022
4.7.0-dev.8509 145 10/31/2022
4.7.0-dev.8377 843 10/26/2022
4.7.0-dev.8360 172 10/25/2022
4.7.0-dev.8350 207 10/24/2022
4.7.0-dev.8335 161 10/24/2022
4.7.0-dev.8334 162 10/24/2022
4.7.0-dev.8223 252 10/19/2022
4.7.0-dev.8178 273 10/17/2022
4.7.0-dev.8170 154 10/17/2022
4.7.0-dev.8148 158 10/17/2022
4.7.0-dev.8133 153 10/17/2022
4.7.0-dev.8097 141 10/17/2022
4.7.0-dev.8034 1,111 10/11/2022
4.7.0-dev.8025 188 10/11/2022
4.7.0-dev.8009 230 10/10/2022
4.7.0-dev.8001 166 10/10/2022
4.7.0-dev.7959 236 10/4/2022
4.7.0-dev.7905 360 9/30/2022
4.7.0-dev.7875 206 9/29/2022
4.6.0 50,916 9/29/2022
4.6.0-dev.7832 200 9/29/2022
4.6.0-dev.7817 164 9/29/2022
4.6.0-dev.7779 221 9/27/2022
4.6.0-dev.7778 176 9/27/2022
4.6.0-dev.7734 193 9/26/2022
4.6.0-dev.7733 161 9/26/2022
4.6.0-dev.7677 267 9/20/2022
4.6.0-dev.7650 261 9/16/2022
4.6.0-dev.7626 238 9/14/2022
4.6.0-dev.7618 216 9/14/2022
4.6.0-dev.7574 167 9/13/2022
4.6.0-dev.7572 148 9/13/2022
4.6.0-dev.7528 297 9/12/2022
4.6.0-dev.7502 193 9/9/2022
4.6.0-dev.7479 221 9/8/2022
4.6.0-dev.7471 176 9/8/2022
4.6.0-dev.7447 225 9/7/2022
4.6.0-dev.7425 163 9/7/2022
4.6.0-dev.7395 187 9/6/2022
4.6.0-dev.7344 367 8/31/2022
4.6.0-dev.7329 152 8/31/2022
4.6.0-dev.7292 166 8/30/2022
4.6.0-dev.7240 349 8/29/2022
4.5.0 72,087 8/29/2022
4.5.0-dev.7216 179 8/27/2022
4.5.0-dev.7147 337 8/22/2022
4.5.0-dev.7134 374 8/17/2022
4.5.0-dev.7096 213 8/15/2022
4.5.0-dev.7070 308 8/11/2022
4.5.0-dev.7040 221 8/10/2022
4.5.0-dev.7011 273 8/3/2022
4.5.0-dev.6987 182 8/1/2022
4.5.0-dev.6962 193 7/29/2022
4.4.0 50,921 7/29/2022
4.4.0-dev.6901 371 7/25/2022
4.4.0-dev.6843 411 7/19/2022
4.4.0-dev.6804 182 7/19/2022
4.4.0-dev.6789 173 7/19/2022
4.4.0-dev.6760 169 7/19/2022
4.4.0-dev.6705 256 7/14/2022
4.4.0-dev.6663 1,166 6/24/2022
4.4.0-dev.6655 188 6/24/2022
4.3.0 208,353 6/24/2022
4.3.0-dev.multiple.buckets3 327 6/21/2022
4.3.0-dev.multiple.buckets2 299 6/17/2022
4.3.0-dev.multiple.buckets1 168 6/17/2022
4.3.0-dev.6631 181 6/22/2022
4.3.0-dev.6623 163 6/22/2022
4.3.0-dev.6374 492 6/13/2022
4.3.0-dev.6286 1,024 5/20/2022
4.2.0 80,395 5/20/2022
4.2.0-dev.6257 645 5/13/2022
4.2.0-dev.6248 184 5/12/2022
4.2.0-dev.6233 271 5/12/2022
4.2.0-dev.6194 281 5/10/2022
4.2.0-dev.6193 195 5/10/2022
4.2.0-dev.6158 3,091 5/6/2022
4.2.0-dev.6135 236 5/6/2022
4.2.0-dev.6091 571 4/28/2022
4.2.0-dev.6048 208 4/28/2022
4.2.0-dev.6047 186 4/28/2022
4.2.0-dev.5966 537 4/25/2022
4.2.0-dev.5938 437 4/19/2022
4.1.0 48,408 4/19/2022
4.1.0-dev.5910 399 4/13/2022
4.1.0-dev.5888 193 4/13/2022
4.1.0-dev.5887 201 4/13/2022
4.1.0-dev.5794 893 4/6/2022
4.1.0-dev.5725 673 3/18/2022
4.0.0 61,826 3/18/2022
4.0.0-rc3 1,035 3/4/2022
4.0.0-rc2 761 2/25/2022
4.0.0-rc1 2,247 2/18/2022
4.0.0-dev.5709 193 3/18/2022
4.0.0-dev.5684 203 3/15/2022
4.0.0-dev.5630 192 3/4/2022
4.0.0-dev.5607 202 3/3/2022
4.0.0-dev.5579 206 2/25/2022
4.0.0-dev.5556 201 2/24/2022
4.0.0-dev.5555 204 2/24/2022
4.0.0-dev.5497 203 2/23/2022
4.0.0-dev.5489 189 2/23/2022
4.0.0-dev.5460 197 2/23/2022
4.0.0-dev.5444 203 2/22/2022
4.0.0-dev.5333 215 2/17/2022
4.0.0-dev.5303 208 2/16/2022
4.0.0-dev.5280 202 2/16/2022
4.0.0-dev.5279 201 2/16/2022
4.0.0-dev.5241 388 2/15/2022
4.0.0-dev.5225 213 2/15/2022
4.0.0-dev.5217 194 2/15/2022
4.0.0-dev.5209 196 2/15/2022
4.0.0-dev.5200 207 2/14/2022
4.0.0-dev.5188 759 2/10/2022
4.0.0-dev.5180 420 2/10/2022
4.0.0-dev.5172 420 2/10/2022
4.0.0-dev.5130 427 2/10/2022
4.0.0-dev.5122 434 2/9/2022
4.0.0-dev.5103 436 2/9/2022
4.0.0-dev.5097 432 2/9/2022
4.0.0-dev.5091 414 2/9/2022
4.0.0-dev.5084 408 2/8/2022
3.4.0-dev.5263 208 2/15/2022
3.4.0-dev.4986 443 2/7/2022
3.4.0-dev.4968 473 2/4/2022
3.3.0 166,749 2/4/2022
3.3.0-dev.4889 463 2/3/2022
3.3.0-dev.4865 461 2/1/2022
3.3.0-dev.4823 376 1/19/2022
3.3.0-dev.4691 1,481 1/7/2022
3.3.0-dev.4557 2,262 11/26/2021
3.2.0 102,024 11/26/2021
3.2.0-dev.4533 5,123 11/24/2021
3.2.0-dev.4484 409 11/11/2021
3.2.0-dev.4475 270 11/10/2021
3.2.0-dev.4387 337 10/26/2021
3.2.0-dev.4363 298 10/22/2021
3.2.0-dev.4356 245 10/22/2021
3.1.0 97,405 10/22/2021
3.1.0-dev.4303 493 10/18/2021
3.1.0-dev.4293 268 10/15/2021
3.1.0-dev.4286 251 10/15/2021
3.1.0-dev.4240 301 10/12/2021
3.1.0-dev.4202 260 10/11/2021
3.1.0-dev.4183 270 10/11/2021
3.1.0-dev.4131 242 10/8/2021
3.1.0-dev.3999 266 10/5/2021
3.1.0-dev.3841 379 9/29/2021
3.1.0-dev.3798 460 9/17/2021
3.0.0 64,800 9/17/2021
3.0.0-dev.3726 2,593 8/31/2021
3.0.0-dev.3719 222 8/31/2021
3.0.0-dev.3671 472 8/20/2021
2.2.0-dev.3652 229 8/20/2021
2.1.0 339,734 8/20/2021
2.1.0-dev.3605 269 8/17/2021
2.1.0-dev.3584 580 8/16/2021
2.1.0-dev.3558 232 8/16/2021
2.1.0-dev.3527 372 7/29/2021
2.1.0-dev.3519 291 7/29/2021
2.1.0-dev.3490 363 7/20/2021
2.1.0-dev.3445 316 7/12/2021
2.1.0-dev.3434 299 7/9/2021
2.0.0 69,537 7/9/2021
2.0.0-dev.3401 8,067 6/25/2021
2.0.0-dev.3368 302 6/23/2021
2.0.0-dev.3361 293 6/23/2021
2.0.0-dev.3330 313 6/17/2021
2.0.0-dev.3291 299 6/16/2021
1.20.0-dev.3218 576 6/4/2021
1.19.0 165,338 6/4/2021
1.19.0-dev.3204 270 6/3/2021
1.19.0-dev.3160 263 6/2/2021
1.19.0-dev.3159 232 6/2/2021
1.19.0-dev.3084 2,560 5/7/2021
1.19.0-dev.3051 316 5/5/2021
1.19.0-dev.3044 271 5/5/2021
1.19.0-dev.3008 306 4/30/2021
1.18.0 37,839 4/30/2021
1.18.0-dev.2973 298 4/27/2021
1.18.0-dev.2930 1,249 4/16/2021
1.18.0-dev.2919 292 4/13/2021
1.18.0-dev.2893 290 4/12/2021
1.18.0-dev.2880 262 4/12/2021
1.18.0-dev.2856 287 4/7/2021
1.18.0-dev.2830 1,890 4/1/2021
1.18.0-dev.2816 254 4/1/2021
1.17.0 49,088 4/1/2021
1.17.0-dev.linq.17 933 3/18/2021
1.17.0-dev.linq.16 303 3/16/2021
1.17.0-dev.linq.15 284 3/15/2021
1.17.0-dev.linq.14 300 3/12/2021
1.17.0-dev.linq.13 337 3/11/2021
1.17.0-dev.linq.12 264 3/10/2021
1.17.0-dev.linq.11 304 3/8/2021
1.17.0-dev.2776 272 3/26/2021
1.17.0-dev.2713 246 3/25/2021
1.17.0-dev.2707 242 3/25/2021
1.17.0-dev.2652 306 3/19/2021
1.17.0-dev.2619 240 3/18/2021
1.17.0-dev.2566 245 3/16/2021
1.17.0-dev.2549 250 3/15/2021
1.17.0-dev.2505 283 3/12/2021
1.17.0-dev.2446 271 3/11/2021
1.17.0-dev.2402 268 3/8/2021
1.17.0-dev.2371 264 3/5/2021
1.16.0 19,703 3/5/2021
1.16.0-dev.linq.10 1,705 2/4/2021
1.16.0-dev.linq.9 286 2/4/2021
1.16.0-dev.2359 298 3/4/2021
1.16.0-dev.2273 265 2/12/2021
1.16.0-dev.2255 264 2/11/2021
1.16.0-dev.2228 275 2/5/2021
1.16.0-dev.2147 304 1/29/2021
1.15.0 34,068 1/29/2021
1.15.0-dev.linq.8 270 1/28/2021
1.15.0-dev.linq.7 259 1/27/2021
1.15.0-dev.linq.6 335 1/20/2021
1.15.0-dev.linq.5 309 1/19/2021
1.15.0-dev.linq.4 444 1/15/2021
1.15.0-dev.linq.3 259 1/14/2021
1.15.0-dev.linq.2 272 1/13/2021
1.15.0-dev.linq.1 287 1/12/2021
1.15.0-dev.2135 261 1/28/2021
1.15.0-dev.2009 269 1/19/2021
1.15.0-dev.1793 277 1/11/2021
1.15.0-dev.1753 314 1/7/2021
1.15.0-dev.1752 304 1/7/2021
1.15.0-dev.1705 924 12/16/2020
1.15.0-dev.1677 628 12/4/2020
1.14.0 46,531 12/4/2020
1.14.0-dev.1665 321 12/3/2020
1.14.0-dev.1648 320 12/2/2020
1.14.0-dev.1632 381 11/27/2020
1.14.0-dev.1577 516 10/30/2020
1.14.0-dev.1571 379 10/30/2020
1.13.0 15,446 10/30/2020
1.13.0-dev.1545 468 10/15/2020
1.13.0-dev.1516 529 10/8/2020
1.13.0-dev.1489 630 10/2/2020
1.13.0-dev.1478 368 10/2/2020
1.12.0 40,802 10/2/2020
1.12.0-dev.1466 315 10/1/2020
1.12.0-dev.1421 614 9/23/2020
1.12.0-dev.1345 381 9/18/2020
1.12.0-dev.1306 382 9/15/2020
1.12.0-dev.1251 394 9/2/2020
1.12.0-dev.1216 2,006 8/14/2020
1.11.0 24,418 8/14/2020
1.11.0-dev.1205 351 8/14/2020
1.11.0-dev.1185 351 8/10/2020
1.11.0-dev.1166 404 7/28/2020
1.11.0-dev.1150 352 7/28/2020
1.11.0-dev.1144 369 7/28/2020
1.11.0-dev.1125 351 7/20/2020
1.11.0-dev.1111 352 7/17/2020
1.10.0 17,330 7/17/2020
1.10.0-dev.1098 333 7/15/2020
1.10.0-dev.1077 445 7/10/2020
1.10.0-dev.1049 459 6/29/2020
1.10.0-dev.1022 378 6/23/2020
1.10.0-dev.1021 361 6/23/2020
1.10.0-dev.990 364 6/19/2020
1.9.0 26,418 6/19/2020
1.9.0-dev.984 379 6/19/2020
1.9.0-dev.971 337 6/17/2020
1.9.0-dev.955 344 6/17/2020
1.9.0-dev.886 360 6/10/2020
1.9.0-dev.848 379 6/8/2020
1.9.0-dev.842 337 6/8/2020
1.9.0-dev.836 335 6/8/2020
1.9.0-dev.786 1,313 5/27/2020
1.9.0-dev.762 646 5/15/2020
1.8.0 18,741 5/15/2020
1.8.0-dev.748 354 5/12/2020
1.8.0-dev.669 610 4/22/2020
1.8.0-dev.668 347 4/21/2020
1.8.0-dev.661 343 4/20/2020
1.8.0-dev.650 338 4/20/2020
1.8.0-dev.639 352 4/20/2020
1.8.0-dev.620 346 4/17/2020
1.7.0 15,295 4/17/2020
1.7.0-dev.608 375 4/16/2020
1.7.0-dev.574 341 4/14/2020
1.7.0-dev.563 341 4/14/2020
1.7.0-dev.534 356 4/6/2020
1.7.0-dev.528 362 4/6/2020
1.7.0-dev.512 392 4/3/2020
1.7.0-dev.495 360 3/30/2020
1.7.0-dev.469 1,209 3/13/2020
1.6.0 2,996 3/13/2020
1.6.0-dev.458 380 3/13/2020
1.6.0-dev.443 375 3/9/2020
1.6.0-dev.422 385 2/28/2020
1.6.0-dev.410 388 2/27/2020
1.6.0-dev.404 390 2/27/2020
1.6.0-dev.356 383 2/14/2020
1.5.0 2,121 2/14/2020
1.5.0-dev.349 362 2/14/2020
1.5.0-dev.341 365 2/12/2020
1.5.0-dev.312 378 1/22/2020
1.4.0 4,140 1/17/2020
1.3.0 2,099 12/6/2019
1.2.0 6,261 11/8/2019
1.1.0 1,010 10/11/2019
1.0.0 5,628 8/23/2019