I'm using the latest C# client and attempting to write data to InfluxDB using the lineprotocol.
This works:
'RobotStarted,instr=GBPUSD,timeframe=12H index=0i 1623046961909067000'
But I receive a parse error when I add in a string field using double-quotes:
{"code":"invalid","message":"unable to parse 'RobotStarted,instr=GBPUSD,timeframe=12H server=\"2021-06-07T06:22:41Z\" index=0i 1623046961909067000': bad timestamp"}
I want to be able to enquote my strings as some can potentially contain spaces etc.
Here's the code I'm using:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Core;
using Xunit;
namespace Foo
{
public class RobotEvent
{
public int Index { get; set; }
public string HostId { get; set; }
public DateTime OpenTime { get; set; }
public DateTime ServerTime { get; set; }
public string SymbolName { get; set; }
public string TimeFrame { get; set; }
}
public class InfluxTests
{
private const string Token = "<token>";
private const string Url = "<url>";
private const string Bucket = "<bucket>";
private const string OrgId = "<org>";
[Fact]
public async Task Should_Write_To_InfluxDB()
{
using (var repo = new InfluxRepository(Url, Token, Bucket, OrgId))
{
try
{
var e = new RobotEvent
{
HostId = "localhost",
OpenTime = DateTime.UtcNow,
ServerTime = DateTime.UtcNow,
SymbolName = "GBPUSD",
TimeFrame = "12H"
};
repo.WriteEvents(e);
var events = await repo.ReadEvents();
Assert.NotNull(events);
Assert.NotEmpty(events);
}
finally
{
await repo.DeleteAll();
}
}
}
}
public static class InfluxEventExtensions
{
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
public static string ToLineProtocol(this RobotEvent e)
{
var unixTicks = GetUnixTicks(e.OpenTime);
var lineProtocol = $"{e.GetType().Name},instr={e.SymbolName},timeframe={e.TimeFrame} server=\"{e.ServerTime.ToISOString()}Z\" index={e.Index}i {unixTicks}00"; // fails
// var lineProtocol = @$"{e.GetType().Name},instr={e.SymbolName},timeframe={e.TimeFrame} index={e.Index}i {unixTicks}00"; // works
return lineProtocol;
}
private static string ToISOString(this DateTime value)
{
return value.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}
private static long GetUnixTicks(DateTime? time = null)
{
return ((time ?? DateTime.UtcNow) - UnixEpoch).Ticks;
}
}
public class InfluxRepository : IDisposable
{
private readonly string _bucketName;
private readonly string _orgId;
private readonly InfluxDBClient _client;
public InfluxRepository(string url, string token, string bucketName, string orgId)
{
_bucketName = bucketName;
_orgId = orgId;
_client = InfluxDBClientFactory.Create(InfluxDBClientOptions.Builder
.CreateNew()
.AuthenticateToken(token)
.Bucket(_bucketName)
.Org(_orgId)
.LogLevel(LogLevel.Body)
.Url(url)
.Build());
}
public void WriteEvents(params RobotEvent[] events)
{
using var writeApi = _client.GetWriteApi();
var records = events.Select(e => e.ToLineProtocol()).ToList();
writeApi.WriteRecords(_bucketName, _orgId, WritePrecision.Ns, records);
}
public async Task<IEnumerable<string>> ReadEvents()
{
var flux =$"from(bucket:\"{_bucketName}\") |> range(start: 0)";
var fluxTables = await _client.GetQueryApi().QueryAsync(flux, _orgId);
var results = new List<string>();
fluxTables.ForEach(fluxTable =>
{
fluxTable.Records.ForEach(fluxRecord =>
{
results.Add($"{fluxRecord.GetTime()}: {fluxRecord.GetValue()}");
});
});
return results;
}
public async Task DeleteAll()
{
var deleteApi = _client.GetDeleteApi();
var predicate = new DeletePredicateRequest();
await deleteApi.Delete(predicate, _bucketName, _orgId);
}
public void Dispose()
{
_client?.Dispose();
}
}
}
{"code":"invalid","message":"unable to parse 'RobotStarted,instr=GBPUSD,timeframe=12H server="2021-06-07T06:22:41Z" index=0i 1623046961909067000': bad timestamp"}
you have to separate fields by comma:
RobotStarted,instr=GBPUSD,timeframe=12H server="2021-06-07T06:22:41Z" index=0i 1623046961909067000 => RobotStarted,instr=GBPUSD,timeframe=12H server="2021-06-07T06:22:41Z",index=0i 1623046961909067000