InfluxDB.Client
4.14.0
See the version list below for details.
dotnet add package InfluxDB.Client --version 4.14.0
NuGet\Install-Package InfluxDB.Client -Version 4.14.0
<PackageReference Include="InfluxDB.Client" Version="4.14.0" />
paket add InfluxDB.Client --version 4.14.0
#r "nuget: InfluxDB.Client, 4.14.0"
// Install InfluxDB.Client as a Cake Addin #addin nuget:?package=InfluxDB.Client&version=4.14.0 // Install InfluxDB.Client as a Cake Tool #tool nuget:?package=InfluxDB.Client&version=4.14.0
InfluxDB.Client
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
- Querying data using Flux language
- Writing data using
- Delete data
- InfluxDB 2.x Management API
- sources, buckets
- tasks
- authorizations
- health check
- Advanced Usage
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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
var queryApi = client.GetQueryApi();
//
// QueryData
//
var tables = await queryApi.QueryAsync(flux, "org_id");
tables.ForEach(table =>
{
table.Records.ForEach(record =>
{
Console.WriteLine($"{record.GetTime()}: {record.GetValueByKey("_value")}");
});
});
}
}
}
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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
var queryApi = client.GetQueryApi();
//
// QueryData
//
var temperatures = await queryApi.QueryAsync<Temperature>(flux, "org_id");
temperatures.ForEach(temperature =>
{
Console.WriteLine($"{temperature.Location}: {temperature.Value} at {temperature.Time}");
});
}
[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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
var queryApi = client.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");
}
}
}
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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
var queryApi = client.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");
}
[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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
var queryApi = client.GetQueryApi();
//
// QueryData
//
var csv = await queryApi.QueryRawAsync(flux, org: "org_id");
Console.WriteLine($"CSV response: {csv}");
}
}
}
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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
var queryApi = client.GetQueryApi();
//
// QueryData
//
await queryApi.QueryRawAsync(flux, line =>
{
//
// The callback to consume a line of CSV response
//
Console.WriteLine($"Response: {line}");
}, org: "org_id");
}
}
}
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()
{
using var client = new InfluxDBClient("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:
- writing data using InfluxDB Line Protocol, Data Point, POCO
- use batching for writes
- produces events that allow user to be notified and react to this events
WriteSuccessEvent
- published when arrived the success response from serverWriteErrorEvent
- published when occurs a unhandled exception from serverWriteRetriableErrorEvent
- published when occurs a retriable error from serverWriteRuntimeExceptionEvent
- published when occurs a runtime exception in background batch processing
- 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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
//
// Write Data
//
using (var writeApi = client.GetWriteApi())
{
//
// Write by POCO
//
var temperature = new Temperature {Location = "south", Value = 62D, Time = DateTime.UtcNow};
writeApi.WriteMeasurement(temperature, WritePrecision.Ns, "bucket_name", "org_id");
}
}
[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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
//
// Write Data
//
using (var writeApi = client.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");
}
}
}
}
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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
//
// Write Data
//
using (var writeApi = client.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");
}
}
}
}
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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
//
// Write Data
//
using (var writeApi = client.GetWriteApi())
{
//
//
// Write by LineProtocol
//
writeApi.WriteRecord("temperature,location=north value=60.0", WritePrecision.Ns,"bucket_name", "org_id");
}
}
}
}
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()
{
using var client = new InfluxDBClient("http://localhost:8086",
"my-user", "my-password");
//
// Write Data
//
var writeApiAsync = client.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()}");
});
});
}
}
}
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(Url)
{
Token = token,
DefaultTags = new Dictionary<string, string>
{
{"id", "132-987-655"},
{"customer", "California Miner"},
}
};
options.AddDefaultTag("hostname", "${env.Hostname}")
options.AddDefaultTags(new Dictionary<string, string>{{ "sensor-version", "${SensorVersion}" }})
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 serverWriteErrorEvent
- for unhandled exception from serverWriteRetriableErrorEvent
- for retriable error from serverWriteRuntimeExceptionEvent
- 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()
{
using var client = new InfluxDBClient("http://localhost:8086", Token);
//
// Delete data
//
await client.GetDeleteApi().Delete(DateTime.UtcNow.AddMinutes(-1), DateTime.Now, "", "bucket", "org");
}
}
}
Filter trace verbose
You can filter out verbose messages from InfluxDB.Client
by using TraceListener.
using System;
using System.Diagnostics;
using InfluxDB.Client.Core;
namespace Examples
{
public static class MyProgram
{
public static void Main()
{
TraceListener ConsoleOutListener = new TextWriterTraceListener(Console.Out)
{
Filter = CategoryTraceFilter.SuppressInfluxVerbose(),
};
Trace.Listeners.Add(ConsoleOutListener);
// My code ...
}
}
}
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()
{
const string url = "http://localhost:8086";
const string token = "my-token";
const string org = "my-org";
using var client = new InfluxDBClient(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(host)
{
Token = token,
Org = organization,
Bucket = bucket
};
var converter = new DomainEntityConverter();
using var client = new InfluxDBClient(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()));
}
}
}
- sources: CustomDomainMapping.cs
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 client = 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 client = new InfluxDBClient("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
You can configure the client to tunnel requests through an HTTP proxy. The WebProxy
could be
configured via InfluxDBClientOptions
parameter WebProxy
:
var options = new InfluxDBClientOptions("http://localhost:8086")
{
Token = "my-token",
WebProxy = new WebProxy("http://proxyserver:80/", true)
};
var client = new InfluxDBClient(options);
Redirects configuration
Client automatically doesn't follows HTTP redirects. You can enable redirects by AllowRedirects
configuration option:
var options = new InfluxDBClientOptions("http://localhost:8086")
{
Token = "my-token",
AllowRedirects = true
};
using var client = new InfluxDBClient(options);
⚠️ Due to a security reason
Authorization
header is not forwarded when redirect leads to a different domain. You can create customAuthenticator
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.
client.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 | Versions 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. |
.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. |
-
.NETStandard 2.0
- InfluxDB.Client.Core (>= 4.14.0)
- JsonSubTypes (>= 2.0.1)
- Microsoft.Extensions.ObjectPool (>= 7.0.13)
- Microsoft.Net.Http.Headers (>= 2.2.8)
- System.Collections.Immutable (>= 6.0.0)
- System.Configuration.ConfigurationManager (>= 6.0.1)
- System.Reactive (>= 6.0.0)
-
.NETStandard 2.1
- InfluxDB.Client.Core (>= 4.14.0)
- JsonSubTypes (>= 2.0.1)
- Microsoft.Extensions.ObjectPool (>= 7.0.13)
- Microsoft.Net.Http.Headers (>= 2.2.8)
- System.Collections.Immutable (>= 6.0.0)
- System.Configuration.ConfigurationManager (>= 6.0.1)
- System.Reactive (>= 6.0.0)
NuGet packages (30)
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 |
|
IoTSharp.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 5 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.
|
|
ConcreteMC/Alex
A Minecraft client written in C# aimed at compatibility with MC:Java & MC:Bedrock
|
|
melanchall/drywetmidi
.NET library to read, write, process MIDI files and to work with MIDI devices
|
Version | Downloads | Last updated |
---|---|---|
4.19.0-dev.14906 | 172 | 10/2/2024 |
4.19.0-dev.14897 | 42 | 10/2/2024 |
4.19.0-dev.14896 | 49 | 10/2/2024 |
4.19.0-dev.14895 | 60 | 10/2/2024 |
4.19.0-dev.14811 | 158 | 9/13/2024 |
4.18.0 | 34,558 | 9/13/2024 |
4.18.0-dev.14769 | 114 | 9/4/2024 |
4.18.0-dev.14743 | 68 | 9/3/2024 |
4.18.0-dev.14694 | 63 | 9/3/2024 |
4.18.0-dev.14693 | 49 | 9/3/2024 |
4.18.0-dev.14692 | 51 | 9/3/2024 |
4.18.0-dev.14618 | 64 | 9/2/2024 |
4.18.0-dev.14609 | 55 | 9/2/2024 |
4.18.0-dev.14592 | 50 | 9/2/2024 |
4.18.0-dev.14446 | 356 | 8/19/2024 |
4.18.0-dev.14414 | 141 | 8/12/2024 |
4.17.0 | 50,562 | 8/12/2024 |
4.17.0-dev.headers.read.1 | 170 | 7/22/2024 |
4.17.0-dev.14350 | 41 | 8/5/2024 |
4.17.0-dev.14333 | 40 | 8/5/2024 |
4.17.0-dev.14300 | 40 | 8/5/2024 |
4.17.0-dev.14291 | 38 | 8/5/2024 |
4.17.0-dev.14189 | 84 | 7/23/2024 |
4.17.0-dev.14179 | 57 | 7/22/2024 |
4.17.0-dev.14101 | 200 | 7/1/2024 |
4.17.0-dev.14100 | 59 | 7/1/2024 |
4.17.0-dev.14044 | 98 | 6/24/2024 |
4.16.0 | 32,170 | 6/24/2024 |
4.16.0-dev.13990 | 1,420 | 6/3/2024 |
4.16.0-dev.13973 | 58 | 6/3/2024 |
4.16.0-dev.13972 | 56 | 6/3/2024 |
4.16.0-dev.13963 | 65 | 6/3/2024 |
4.16.0-dev.13962 | 60 | 6/3/2024 |
4.16.0-dev.13881 | 58 | 6/3/2024 |
4.16.0-dev.13775 | 161 | 5/17/2024 |
4.16.0-dev.13702 | 66 | 5/17/2024 |
4.15.0 | 34,481 | 5/17/2024 |
4.15.0-dev.13674 | 82 | 5/14/2024 |
4.15.0-dev.13567 | 854 | 4/2/2024 |
4.15.0-dev.13558 | 62 | 4/2/2024 |
4.15.0-dev.13525 | 60 | 4/2/2024 |
4.15.0-dev.13524 | 64 | 4/2/2024 |
4.15.0-dev.13433 | 220 | 3/7/2024 |
4.15.0-dev.13432 | 67 | 3/7/2024 |
4.15.0-dev.13407 | 97 | 3/7/2024 |
4.15.0-dev.13390 | 65 | 3/7/2024 |
4.15.0-dev.13388 | 61 | 3/7/2024 |
4.15.0-dev.13282 | 251 | 3/6/2024 |
4.15.0-dev.13257 | 74 | 3/6/2024 |
4.15.0-dev.13113 | 1,121 | 2/1/2024 |
4.15.0-dev.13104 | 69 | 2/1/2024 |
4.15.0-dev.13081 | 69 | 2/1/2024 |
4.15.0-dev.13040 | 129 | 2/1/2024 |
4.15.0-dev.13039 | 68 | 2/1/2024 |
4.15.0-dev.12863 | 2,070 | 1/8/2024 |
4.15.0-dev.12846 | 77 | 1/8/2024 |
4.15.0-dev.12837 | 74 | 1/8/2024 |
4.15.0-dev.12726 | 2,641 | 12/1/2023 |
4.15.0-dev.12725 | 85 | 12/1/2023 |
4.15.0-dev.12724 | 78 | 12/1/2023 |
4.15.0-dev.12691 | 80 | 12/1/2023 |
4.15.0-dev.12658 | 89 | 12/1/2023 |
4.15.0-dev.12649 | 77 | 12/1/2023 |
4.15.0-dev.12624 | 79 | 12/1/2023 |
4.15.0-dev.12471 | 1,018 | 11/7/2023 |
4.15.0-dev.12462 | 81 | 11/7/2023 |
4.14.0 | 422,660 | 11/7/2023 |
4.14.0-dev.12437 | 81 | 11/7/2023 |
4.14.0-dev.12343 | 127 | 11/2/2023 |
4.14.0-dev.12310 | 82 | 11/2/2023 |
4.14.0-dev.12284 | 349 | 11/1/2023 |
4.14.0-dev.12235 | 102 | 11/1/2023 |
4.14.0-dev.12226 | 79 | 11/1/2023 |
4.14.0-dev.11972 | 5,439 | 8/8/2023 |
4.14.0-dev.11915 | 145 | 7/31/2023 |
4.14.0-dev.11879 | 162 | 7/28/2023 |
4.13.0 | 271,107 | 7/28/2023 |
4.13.0-dev.11854 | 101 | 7/28/2023 |
4.13.0-dev.11814 | 357 | 7/21/2023 |
4.13.0-dev.11771 | 145 | 7/19/2023 |
4.13.0-dev.11770 | 106 | 7/19/2023 |
4.13.0-dev.11728 | 126 | 7/18/2023 |
4.13.0-dev.11686 | 202 | 7/17/2023 |
4.13.0-dev.11685 | 90 | 7/17/2023 |
4.13.0-dev.11676 | 105 | 7/17/2023 |
4.13.0-dev.11479 | 2,010 | 6/27/2023 |
4.13.0-dev.11478 | 100 | 6/27/2023 |
4.13.0-dev.11477 | 103 | 6/27/2023 |
4.13.0-dev.11396 | 454 | 6/19/2023 |
4.13.0-dev.11395 | 92 | 6/19/2023 |
4.13.0-dev.11342 | 342 | 6/15/2023 |
4.13.0-dev.11330 | 279 | 6/12/2023 |
4.13.0-dev.11305 | 96 | 6/12/2023 |
4.13.0-dev.11296 | 98 | 6/12/2023 |
4.13.0-dev.11217 | 371 | 6/6/2023 |
4.13.0-dev.11089 | 289 | 5/30/2023 |
4.13.0-dev.11064 | 121 | 5/30/2023 |
4.13.0-dev.10998 | 160 | 5/29/2023 |
4.13.0-dev.10989 | 115 | 5/29/2023 |
4.13.0-dev.10871 | 869 | 5/8/2023 |
4.13.0-dev.10870 | 93 | 5/8/2023 |
4.13.0-dev.10819 | 271 | 4/28/2023 |
4.12.0 | 170,842 | 4/28/2023 |
4.12.0-dev.10777 | 132 | 4/27/2023 |
4.12.0-dev.10768 | 113 | 4/27/2023 |
4.12.0-dev.10759 | 107 | 4/27/2023 |
4.12.0-dev.10742 | 90 | 4/27/2023 |
4.12.0-dev.10685 | 101 | 4/27/2023 |
4.12.0-dev.10684 | 103 | 4/27/2023 |
4.12.0-dev.10643 | 110 | 4/27/2023 |
4.12.0-dev.10642 | 96 | 4/27/2023 |
4.12.0-dev.10569 | 96 | 4/27/2023 |
4.12.0-dev.10193 | 1,742 | 2/23/2023 |
4.11.0 | 110,897 | 2/23/2023 |
4.11.0-dev.10176 | 178 | 2/23/2023 |
4.11.0-dev.10059 | 3,118 | 1/26/2023 |
4.10.0 | 68,689 | 1/26/2023 |
4.10.0-dev.10033 | 143 | 1/25/2023 |
4.10.0-dev.10032 | 120 | 1/25/2023 |
4.10.0-dev.10031 | 133 | 1/25/2023 |
4.10.0-dev.9936 | 3,526 | 12/26/2022 |
4.10.0-dev.9935 | 140 | 12/26/2022 |
4.10.0-dev.9881 | 179 | 12/21/2022 |
4.10.0-dev.9880 | 119 | 12/21/2022 |
4.10.0-dev.9818 | 610 | 12/16/2022 |
4.10.0-dev.9773 | 287 | 12/12/2022 |
4.10.0-dev.9756 | 110 | 12/12/2022 |
4.10.0-dev.9693 | 361 | 12/6/2022 |
4.9.0 | 187,203 | 12/6/2022 |
4.9.0-dev.9684 | 109 | 12/6/2022 |
4.9.0-dev.9666 | 122 | 12/6/2022 |
4.9.0-dev.9617 | 137 | 12/6/2022 |
4.9.0-dev.9478 | 201 | 12/5/2022 |
4.9.0-dev.9469 | 128 | 12/5/2022 |
4.9.0-dev.9444 | 101 | 12/5/2022 |
4.9.0-dev.9411 | 121 | 12/5/2022 |
4.9.0-dev.9350 | 158 | 12/1/2022 |
4.8.0 | 5,538 | 12/1/2022 |
4.8.0-dev.9324 | 201 | 11/30/2022 |
4.8.0-dev.9232 | 182 | 11/28/2022 |
4.8.0-dev.9223 | 120 | 11/28/2022 |
4.8.0-dev.9222 | 116 | 11/28/2022 |
4.8.0-dev.9117 | 404 | 11/21/2022 |
4.8.0-dev.9108 | 122 | 11/21/2022 |
4.8.0-dev.9099 | 122 | 11/21/2022 |
4.8.0-dev.9029 | 193 | 11/16/2022 |
4.8.0-dev.8971 | 124 | 11/15/2022 |
4.8.0-dev.8961 | 127 | 11/14/2022 |
4.8.0-dev.8928 | 134 | 11/14/2022 |
4.8.0-dev.8899 | 132 | 11/14/2022 |
4.8.0-dev.8898 | 142 | 11/14/2022 |
4.8.0-dev.8839 | 131 | 11/14/2022 |
4.8.0-dev.8740 | 243 | 11/7/2022 |
4.8.0-dev.8725 | 120 | 11/7/2022 |
4.8.0-dev.8648 | 362 | 11/3/2022 |
4.7.0 | 101,808 | 11/3/2022 |
4.7.0-dev.8625 | 268 | 11/2/2022 |
4.7.0-dev.8594 | 280 | 10/31/2022 |
4.7.0-dev.8579 | 117 | 10/31/2022 |
4.7.0-dev.8557 | 108 | 10/31/2022 |
4.7.0-dev.8540 | 126 | 10/31/2022 |
4.7.0-dev.8518 | 119 | 10/31/2022 |
4.7.0-dev.8517 | 118 | 10/31/2022 |
4.7.0-dev.8509 | 115 | 10/31/2022 |
4.7.0-dev.8377 | 813 | 10/26/2022 |
4.7.0-dev.8360 | 134 | 10/25/2022 |
4.7.0-dev.8350 | 176 | 10/24/2022 |
4.7.0-dev.8335 | 130 | 10/24/2022 |
4.7.0-dev.8334 | 127 | 10/24/2022 |
4.7.0-dev.8223 | 221 | 10/19/2022 |
4.7.0-dev.8178 | 241 | 10/17/2022 |
4.7.0-dev.8170 | 122 | 10/17/2022 |
4.7.0-dev.8148 | 128 | 10/17/2022 |
4.7.0-dev.8133 | 117 | 10/17/2022 |
4.7.0-dev.8097 | 110 | 10/17/2022 |
4.7.0-dev.8034 | 945 | 10/11/2022 |
4.7.0-dev.8025 | 146 | 10/11/2022 |
4.7.0-dev.8009 | 199 | 10/10/2022 |
4.7.0-dev.8001 | 136 | 10/10/2022 |
4.7.0-dev.7959 | 203 | 10/4/2022 |
4.7.0-dev.7905 | 329 | 9/30/2022 |
4.7.0-dev.7875 | 174 | 9/29/2022 |
4.6.0 | 47,484 | 9/29/2022 |
4.6.0-dev.7832 | 168 | 9/29/2022 |
4.6.0-dev.7817 | 131 | 9/29/2022 |
4.6.0-dev.7779 | 192 | 9/27/2022 |
4.6.0-dev.7778 | 139 | 9/27/2022 |
4.6.0-dev.7734 | 160 | 9/26/2022 |
4.6.0-dev.7733 | 129 | 9/26/2022 |
4.6.0-dev.7677 | 237 | 9/20/2022 |
4.6.0-dev.7650 | 229 | 9/16/2022 |
4.6.0-dev.7626 | 202 | 9/14/2022 |
4.6.0-dev.7618 | 184 | 9/14/2022 |
4.6.0-dev.7574 | 133 | 9/13/2022 |
4.6.0-dev.7572 | 116 | 9/13/2022 |
4.6.0-dev.7528 | 266 | 9/12/2022 |
4.6.0-dev.7502 | 161 | 9/9/2022 |
4.6.0-dev.7479 | 190 | 9/8/2022 |
4.6.0-dev.7471 | 135 | 9/8/2022 |
4.6.0-dev.7447 | 192 | 9/7/2022 |
4.6.0-dev.7425 | 129 | 9/7/2022 |
4.6.0-dev.7395 | 154 | 9/6/2022 |
4.6.0-dev.7344 | 334 | 8/31/2022 |
4.6.0-dev.7329 | 117 | 8/31/2022 |
4.6.0-dev.7292 | 132 | 8/30/2022 |
4.6.0-dev.7240 | 315 | 8/29/2022 |
4.5.0 | 63,017 | 8/29/2022 |
4.5.0-dev.7216 | 146 | 8/27/2022 |
4.5.0-dev.7147 | 304 | 8/22/2022 |
4.5.0-dev.7134 | 341 | 8/17/2022 |
4.5.0-dev.7096 | 180 | 8/15/2022 |
4.5.0-dev.7070 | 277 | 8/11/2022 |
4.5.0-dev.7040 | 190 | 8/10/2022 |
4.5.0-dev.7011 | 239 | 8/3/2022 |
4.5.0-dev.6987 | 146 | 8/1/2022 |
4.5.0-dev.6962 | 158 | 7/29/2022 |
4.4.0 | 49,376 | 7/29/2022 |
4.4.0-dev.6901 | 339 | 7/25/2022 |
4.4.0-dev.6843 | 379 | 7/19/2022 |
4.4.0-dev.6804 | 144 | 7/19/2022 |
4.4.0-dev.6789 | 136 | 7/19/2022 |
4.4.0-dev.6760 | 134 | 7/19/2022 |
4.4.0-dev.6705 | 223 | 7/14/2022 |
4.4.0-dev.6663 | 1,119 | 6/24/2022 |
4.4.0-dev.6655 | 155 | 6/24/2022 |
4.3.0 | 172,977 | 6/24/2022 |
4.3.0-dev.multiple.buckets3 | 292 | 6/21/2022 |
4.3.0-dev.multiple.buckets2 | 265 | 6/17/2022 |
4.3.0-dev.multiple.buckets1 | 134 | 6/17/2022 |
4.3.0-dev.6631 | 145 | 6/22/2022 |
4.3.0-dev.6623 | 130 | 6/22/2022 |
4.3.0-dev.6374 | 457 | 6/13/2022 |
4.3.0-dev.6286 | 989 | 5/20/2022 |
4.2.0 | 71,195 | 5/20/2022 |
4.2.0-dev.6257 | 609 | 5/13/2022 |
4.2.0-dev.6248 | 148 | 5/12/2022 |
4.2.0-dev.6233 | 237 | 5/12/2022 |
4.2.0-dev.6194 | 244 | 5/10/2022 |
4.2.0-dev.6193 | 159 | 5/10/2022 |
4.2.0-dev.6158 | 3,055 | 5/6/2022 |
4.2.0-dev.6135 | 200 | 5/6/2022 |
4.2.0-dev.6091 | 530 | 4/28/2022 |
4.2.0-dev.6048 | 169 | 4/28/2022 |
4.2.0-dev.6047 | 148 | 4/28/2022 |
4.2.0-dev.5966 | 499 | 4/25/2022 |
4.2.0-dev.5938 | 396 | 4/19/2022 |
4.1.0 | 46,983 | 4/19/2022 |
4.1.0-dev.5910 | 361 | 4/13/2022 |
4.1.0-dev.5888 | 156 | 4/13/2022 |
4.1.0-dev.5887 | 162 | 4/13/2022 |
4.1.0-dev.5794 | 853 | 4/6/2022 |
4.1.0-dev.5725 | 569 | 3/18/2022 |
4.0.0 | 58,864 | 3/18/2022 |
4.0.0-rc3 | 992 | 3/4/2022 |
4.0.0-rc2 | 719 | 2/25/2022 |
4.0.0-rc1 | 2,200 | 2/18/2022 |
4.0.0-dev.5709 | 154 | 3/18/2022 |
4.0.0-dev.5684 | 165 | 3/15/2022 |
4.0.0-dev.5630 | 151 | 3/4/2022 |
4.0.0-dev.5607 | 160 | 3/3/2022 |
4.0.0-dev.5579 | 166 | 2/25/2022 |
4.0.0-dev.5556 | 163 | 2/24/2022 |
4.0.0-dev.5555 | 158 | 2/24/2022 |
4.0.0-dev.5497 | 164 | 2/23/2022 |
4.0.0-dev.5489 | 150 | 2/23/2022 |
4.0.0-dev.5460 | 157 | 2/23/2022 |
4.0.0-dev.5444 | 162 | 2/22/2022 |
4.0.0-dev.5333 | 177 | 2/17/2022 |
4.0.0-dev.5303 | 169 | 2/16/2022 |
4.0.0-dev.5280 | 157 | 2/16/2022 |
4.0.0-dev.5279 | 161 | 2/16/2022 |
4.0.0-dev.5241 | 346 | 2/15/2022 |
4.0.0-dev.5225 | 169 | 2/15/2022 |
4.0.0-dev.5217 | 151 | 2/15/2022 |
4.0.0-dev.5209 | 153 | 2/15/2022 |
4.0.0-dev.5200 | 168 | 2/14/2022 |
4.0.0-dev.5188 | 716 | 2/10/2022 |
4.0.0-dev.5180 | 378 | 2/10/2022 |
4.0.0-dev.5172 | 378 | 2/10/2022 |
4.0.0-dev.5130 | 385 | 2/10/2022 |
4.0.0-dev.5122 | 395 | 2/9/2022 |
4.0.0-dev.5103 | 393 | 2/9/2022 |
4.0.0-dev.5097 | 392 | 2/9/2022 |
4.0.0-dev.5091 | 372 | 2/9/2022 |
4.0.0-dev.5084 | 366 | 2/8/2022 |
3.4.0-dev.5263 | 165 | 2/15/2022 |
3.4.0-dev.4986 | 400 | 2/7/2022 |
3.4.0-dev.4968 | 428 | 2/4/2022 |
3.3.0 | 143,488 | 2/4/2022 |
3.3.0-dev.4889 | 422 | 2/3/2022 |
3.3.0-dev.4865 | 418 | 2/1/2022 |
3.3.0-dev.4823 | 332 | 1/19/2022 |
3.3.0-dev.4691 | 1,154 | 1/7/2022 |
3.3.0-dev.4557 | 2,218 | 11/26/2021 |
3.2.0 | 96,512 | 11/26/2021 |
3.2.0-dev.4533 | 5,080 | 11/24/2021 |
3.2.0-dev.4484 | 366 | 11/11/2021 |
3.2.0-dev.4475 | 227 | 11/10/2021 |
3.2.0-dev.4387 | 286 | 10/26/2021 |
3.2.0-dev.4363 | 253 | 10/22/2021 |
3.2.0-dev.4356 | 201 | 10/22/2021 |
3.1.0 | 94,494 | 10/22/2021 |
3.1.0-dev.4303 | 449 | 10/18/2021 |
3.1.0-dev.4293 | 226 | 10/15/2021 |
3.1.0-dev.4286 | 207 | 10/15/2021 |
3.1.0-dev.4240 | 261 | 10/12/2021 |
3.1.0-dev.4202 | 217 | 10/11/2021 |
3.1.0-dev.4183 | 226 | 10/11/2021 |
3.1.0-dev.4131 | 201 | 10/8/2021 |
3.1.0-dev.3999 | 223 | 10/5/2021 |
3.1.0-dev.3841 | 336 | 9/29/2021 |
3.1.0-dev.3798 | 416 | 9/17/2021 |
3.0.0 | 60,577 | 9/17/2021 |
3.0.0-dev.3726 | 2,548 | 8/31/2021 |
3.0.0-dev.3719 | 180 | 8/31/2021 |
3.0.0-dev.3671 | 428 | 8/20/2021 |
2.2.0-dev.3652 | 184 | 8/20/2021 |
2.1.0 | 279,285 | 8/20/2021 |
2.1.0-dev.3605 | 223 | 8/17/2021 |
2.1.0-dev.3584 | 537 | 8/16/2021 |
2.1.0-dev.3558 | 190 | 8/16/2021 |
2.1.0-dev.3527 | 328 | 7/29/2021 |
2.1.0-dev.3519 | 248 | 7/29/2021 |
2.1.0-dev.3490 | 319 | 7/20/2021 |
2.1.0-dev.3445 | 274 | 7/12/2021 |
2.1.0-dev.3434 | 259 | 7/9/2021 |
2.0.0 | 65,655 | 7/9/2021 |
2.0.0-dev.3401 | 7,567 | 6/25/2021 |
2.0.0-dev.3368 | 260 | 6/23/2021 |
2.0.0-dev.3361 | 238 | 6/23/2021 |
2.0.0-dev.3330 | 270 | 6/17/2021 |
2.0.0-dev.3291 | 258 | 6/16/2021 |
1.20.0-dev.3218 | 533 | 6/4/2021 |
1.19.0 | 131,367 | 6/4/2021 |
1.19.0-dev.3204 | 227 | 6/3/2021 |
1.19.0-dev.3160 | 218 | 6/2/2021 |
1.19.0-dev.3159 | 189 | 6/2/2021 |
1.19.0-dev.3084 | 2,513 | 5/7/2021 |
1.19.0-dev.3051 | 268 | 5/5/2021 |
1.19.0-dev.3044 | 222 | 5/5/2021 |
1.19.0-dev.3008 | 258 | 4/30/2021 |
1.18.0 | 36,189 | 4/30/2021 |
1.18.0-dev.2973 | 248 | 4/27/2021 |
1.18.0-dev.2930 | 1,203 | 4/16/2021 |
1.18.0-dev.2919 | 244 | 4/13/2021 |
1.18.0-dev.2893 | 243 | 4/12/2021 |
1.18.0-dev.2880 | 210 | 4/12/2021 |
1.18.0-dev.2856 | 241 | 4/7/2021 |
1.18.0-dev.2830 | 1,842 | 4/1/2021 |
1.18.0-dev.2816 | 205 | 4/1/2021 |
1.17.0 | 46,107 | 4/1/2021 |
1.17.0-dev.linq.17 | 884 | 3/18/2021 |
1.17.0-dev.linq.16 | 254 | 3/16/2021 |
1.17.0-dev.linq.15 | 236 | 3/15/2021 |
1.17.0-dev.linq.14 | 252 | 3/12/2021 |
1.17.0-dev.linq.13 | 286 | 3/11/2021 |
1.17.0-dev.linq.12 | 209 | 3/10/2021 |
1.17.0-dev.linq.11 | 255 | 3/8/2021 |
1.17.0-dev.2776 | 225 | 3/26/2021 |
1.17.0-dev.2713 | 192 | 3/25/2021 |
1.17.0-dev.2707 | 195 | 3/25/2021 |
1.17.0-dev.2652 | 254 | 3/19/2021 |
1.17.0-dev.2619 | 192 | 3/18/2021 |
1.17.0-dev.2566 | 194 | 3/16/2021 |
1.17.0-dev.2549 | 201 | 3/15/2021 |
1.17.0-dev.2505 | 236 | 3/12/2021 |
1.17.0-dev.2446 | 220 | 3/11/2021 |
1.17.0-dev.2402 | 217 | 3/8/2021 |
1.17.0-dev.2371 | 214 | 3/5/2021 |
1.16.0 | 19,335 | 3/5/2021 |
1.16.0-dev.linq.10 | 1,647 | 2/4/2021 |
1.16.0-dev.linq.9 | 233 | 2/4/2021 |
1.16.0-dev.2359 | 247 | 3/4/2021 |
1.16.0-dev.2273 | 207 | 2/12/2021 |
1.16.0-dev.2255 | 213 | 2/11/2021 |
1.16.0-dev.2228 | 222 | 2/5/2021 |
1.16.0-dev.2147 | 253 | 1/29/2021 |
1.15.0 | 32,712 | 1/29/2021 |
1.15.0-dev.linq.8 | 217 | 1/28/2021 |
1.15.0-dev.linq.7 | 208 | 1/27/2021 |
1.15.0-dev.linq.6 | 279 | 1/20/2021 |
1.15.0-dev.linq.5 | 257 | 1/19/2021 |
1.15.0-dev.linq.4 | 392 | 1/15/2021 |
1.15.0-dev.linq.3 | 207 | 1/14/2021 |
1.15.0-dev.linq.2 | 220 | 1/13/2021 |
1.15.0-dev.linq.1 | 236 | 1/12/2021 |
1.15.0-dev.2135 | 210 | 1/28/2021 |
1.15.0-dev.2009 | 218 | 1/19/2021 |
1.15.0-dev.1793 | 227 | 1/11/2021 |
1.15.0-dev.1753 | 263 | 1/7/2021 |
1.15.0-dev.1752 | 251 | 1/7/2021 |
1.15.0-dev.1705 | 870 | 12/16/2020 |
1.15.0-dev.1677 | 575 | 12/4/2020 |
1.14.0 | 45,647 | 12/4/2020 |
1.14.0-dev.1665 | 267 | 12/3/2020 |
1.14.0-dev.1648 | 268 | 12/2/2020 |
1.14.0-dev.1632 | 329 | 11/27/2020 |
1.14.0-dev.1577 | 462 | 10/30/2020 |
1.14.0-dev.1571 | 325 | 10/30/2020 |
1.13.0 | 15,162 | 10/30/2020 |
1.13.0-dev.1545 | 415 | 10/15/2020 |
1.13.0-dev.1516 | 475 | 10/8/2020 |
1.13.0-dev.1489 | 578 | 10/2/2020 |
1.13.0-dev.1478 | 315 | 10/2/2020 |
1.12.0 | 36,953 | 10/2/2020 |
1.12.0-dev.1466 | 261 | 10/1/2020 |
1.12.0-dev.1421 | 562 | 9/23/2020 |
1.12.0-dev.1345 | 328 | 9/18/2020 |
1.12.0-dev.1306 | 331 | 9/15/2020 |
1.12.0-dev.1251 | 342 | 9/2/2020 |
1.12.0-dev.1216 | 1,953 | 8/14/2020 |
1.11.0 | 24,286 | 8/14/2020 |
1.11.0-dev.1205 | 299 | 8/14/2020 |
1.11.0-dev.1185 | 299 | 8/10/2020 |
1.11.0-dev.1166 | 352 | 7/28/2020 |
1.11.0-dev.1150 | 298 | 7/28/2020 |
1.11.0-dev.1144 | 313 | 7/28/2020 |
1.11.0-dev.1125 | 296 | 7/20/2020 |
1.11.0-dev.1111 | 295 | 7/17/2020 |
1.10.0 | 17,118 | 7/17/2020 |
1.10.0-dev.1098 | 283 | 7/15/2020 |
1.10.0-dev.1077 | 395 | 7/10/2020 |
1.10.0-dev.1049 | 409 | 6/29/2020 |
1.10.0-dev.1022 | 326 | 6/23/2020 |
1.10.0-dev.1021 | 311 | 6/23/2020 |
1.10.0-dev.990 | 311 | 6/19/2020 |
1.9.0 | 20,306 | 6/19/2020 |
1.9.0-dev.984 | 327 | 6/19/2020 |
1.9.0-dev.971 | 283 | 6/17/2020 |
1.9.0-dev.955 | 288 | 6/17/2020 |
1.9.0-dev.886 | 309 | 6/10/2020 |
1.9.0-dev.848 | 328 | 6/8/2020 |
1.9.0-dev.842 | 282 | 6/8/2020 |
1.9.0-dev.836 | 284 | 6/8/2020 |
1.9.0-dev.786 | 1,259 | 5/27/2020 |
1.9.0-dev.762 | 592 | 5/15/2020 |
1.8.0 | 18,537 | 5/15/2020 |
1.8.0-dev.748 | 301 | 5/12/2020 |
1.8.0-dev.669 | 554 | 4/22/2020 |
1.8.0-dev.668 | 290 | 4/21/2020 |
1.8.0-dev.661 | 287 | 4/20/2020 |
1.8.0-dev.650 | 285 | 4/20/2020 |
1.8.0-dev.639 | 299 | 4/20/2020 |
1.8.0-dev.620 | 287 | 4/17/2020 |
1.7.0 | 14,489 | 4/17/2020 |
1.7.0-dev.608 | 321 | 4/16/2020 |
1.7.0-dev.574 | 288 | 4/14/2020 |
1.7.0-dev.563 | 287 | 4/14/2020 |
1.7.0-dev.534 | 302 | 4/6/2020 |
1.7.0-dev.528 | 301 | 4/6/2020 |
1.7.0-dev.512 | 338 | 4/3/2020 |
1.7.0-dev.495 | 307 | 3/30/2020 |
1.7.0-dev.469 | 1,154 | 3/13/2020 |
1.6.0 | 2,929 | 3/13/2020 |
1.6.0-dev.458 | 328 | 3/13/2020 |
1.6.0-dev.443 | 321 | 3/9/2020 |
1.6.0-dev.422 | 331 | 2/28/2020 |
1.6.0-dev.410 | 335 | 2/27/2020 |
1.6.0-dev.404 | 337 | 2/27/2020 |
1.6.0-dev.356 | 331 | 2/14/2020 |
1.5.0 | 1,543 | 2/14/2020 |
1.5.0-dev.349 | 310 | 2/14/2020 |
1.5.0-dev.341 | 313 | 2/12/2020 |
1.5.0-dev.312 | 325 | 1/22/2020 |
1.4.0 | 4,055 | 1/17/2020 |
1.3.0 | 2,034 | 12/6/2019 |
1.2.0 | 6,192 | 11/8/2019 |
1.1.0 | 938 | 10/11/2019 |
1.0.0 | 3,100 | 8/23/2019 |