Skip to content

Commit 0688621

Browse files
authored
feat: default tags (#66)
1 parent b7dac41 commit 0688621

File tree

6 files changed

+106
-8
lines changed

6 files changed

+106
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## 0.4.0 [unreleased]
22

3+
### Features
4+
5+
1. [#66](https://github.com/InfluxCommunity/influxdb3-csharp/pull/66): Default Tags for Writes
6+
37
## 0.3.0 [2023-10-02]
48

59
### Features

Client.Test/InfluxDBClientWriteTest.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,40 @@ public async Task NotSpecifiedOrg()
143143
Assert.That(requests[0].RequestMessage.Query, Does.Not.ContainKey("org"));
144144
}
145145

146+
[Test]
147+
public async Task DefaultTags()
148+
{
149+
MockServer
150+
.Given(Request.Create().WithPath("/api/v2/write").UsingPost())
151+
.RespondWith(Response.Create().WithStatusCode(204));
152+
153+
_client = new InfluxDBClient(new ClientConfig
154+
{
155+
Host = MockServerUrl,
156+
Token = "my-token",
157+
Organization = "my-org",
158+
Database = "my-database",
159+
WriteOptions = new WriteOptions
160+
{
161+
DefaultTags = new Dictionary<string, string>()
162+
{
163+
{ "tag1", "default" },
164+
{ "tag2", "default" },
165+
}
166+
}
167+
});
168+
169+
await _client.WritePointAsync(PointData
170+
.Measurement("cpu")
171+
.SetTag("tag", "c")
172+
.SetTag("tag2", "c")
173+
.SetField("field", 1)
174+
);
175+
176+
var requests = MockServer.LogEntries.ToList();
177+
Assert.That(requests[0].RequestMessage.BodyData?.BodyAsString, Is.EqualTo("cpu,tag=c,tag1=default,tag2=c field=1i"));
178+
}
179+
146180
[Test]
147181
public async Task DatabaseCustom()
148182
{

Client.Test/Write/PointDataTest.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,24 @@ public void TagEmptyKey()
8686
Assert.That(point.ToLineProtocol(), Is.EqualTo("h2o,location=europe level=2i"));
8787
}
8888

89+
[Test]
90+
public void DefaultTags()
91+
{
92+
var point = PointData.Measurement("h2o")
93+
.SetTag("tag2", "val")
94+
.SetField("field", 1);
95+
96+
var defaultTags = new Dictionary<string, string>() {
97+
{"tag1", "default"},
98+
{"tag2", "--"},
99+
{"a", "b"},
100+
};
101+
102+
Assert.That(point.ToLineProtocol(defaultTags: defaultTags), Is.EqualTo("h2o,a=b,tag1=default,tag2=val field=1i"));
103+
Assert.That(point.ToLineProtocol(defaultTags: null), Is.EqualTo("h2o,tag2=val field=1i"));
104+
Assert.That(point.ToLineProtocol(defaultTags: new Dictionary<string, string>()), Is.EqualTo("h2o,tag2=val field=1i"));
105+
}
106+
89107
[Test]
90108
public void TagEmptyValue()
91109
{

Client/Config/WriteOptions.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using InfluxDB3.Client.Write;
34

45
namespace InfluxDB3.Client.Config;
@@ -33,6 +34,33 @@ public class WriteOptions : ICloneable
3334
/// </summary>
3435
public WritePrecision? Precision { get; set; }
3536

37+
/// <summary>
38+
/// Tags added to each point during writing. If a point already has a tag with the same key, it is left unchanged.
39+
/// <example>
40+
/// <code>
41+
/// <![CDATA[
42+
/// var _client = new InfluxDBClient(new InfluxDBClientConfigs
43+
/// {
44+
/// HostUrl = "some-url",
45+
/// Organization = "org",
46+
/// Database = "database",
47+
/// DefaultTags = new Dictionary \<string, string ()
48+
/// {
49+
/// { "rack", "main" },
50+
/// }
51+
/// });
52+
///
53+
/// // Writes with rack=main tag
54+
/// await _client.WritePointAsync(PointData
55+
/// .Measurement("cpu")
56+
/// .SetField("field", 1)
57+
/// );
58+
/// ]]>
59+
/// </code>
60+
/// </example>
61+
/// </summary>
62+
public Dictionary<string, string>? DefaultTags { get; set; }
63+
3664
/// <summary>
3765
/// The threshold in bytes for gzipping the body.
3866
/// </summary>

Client/InfluxDBClient.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ private async Task WriteData(IEnumerable<object> data, string? database = null,
402402
}
403403

404404
var precisionNotNull = precision ?? _config.WritePrecision;
405-
var sb = ToLineProtocolBody(data, precisionNotNull);
405+
var sb = ToLineProtocolBody(data, precisionNotNull, _config.WriteOptions?.DefaultTags);
406406
if (sb.Length == 0)
407407
{
408408
Trace.WriteLine($"The writes: {data} doesn't contains any Line Protocol, skipping");
@@ -437,15 +437,15 @@ public void Dispose()
437437
_disposed = true;
438438
}
439439

440-
private static StringBuilder ToLineProtocolBody(IEnumerable<object?> data, WritePrecision precision)
440+
private static StringBuilder ToLineProtocolBody(IEnumerable<object?> data, WritePrecision precision, Dictionary<string, string>? defaultTags = null)
441441
{
442442
var sb = new StringBuilder("");
443443

444444
foreach (var item in data)
445445
{
446446
var lineProtocol = item switch
447447
{
448-
PointData pointData => pointData.ToLineProtocol(precision),
448+
PointData pointData => pointData.ToLineProtocol(precision, defaultTags),
449449
_ => item?.ToString()
450450
};
451451

Client/Write/PointData.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Globalization;
4+
using System.Linq;
45
using System.Numerics;
56
using System.Text;
67

@@ -433,13 +434,14 @@ public PointData Copy()
433434
/// Transform to Line Protocol.
434435
/// </summary>
435436
/// <param name="timeUnit">the timestamp precision</param>
437+
/// <param name="defaultTags">Tags added to point</param>
436438
/// <returns>Line Protocol</returns>
437-
public string ToLineProtocol(WritePrecision? timeUnit = null)
439+
public string ToLineProtocol(WritePrecision? timeUnit = null, Dictionary<string, string>? defaultTags = null)
438440
{
439441
var sb = new StringBuilder();
440442

441443
EscapeKey(sb, _values.GetMeasurement()!, false);
442-
AppendTags(sb);
444+
AppendTags(sb, defaultTags);
443445
var appendedFields = AppendFields(sb);
444446
if (!appendedFields)
445447
{
@@ -455,11 +457,23 @@ public string ToLineProtocol(WritePrecision? timeUnit = null)
455457
/// Appends the tags.
456458
/// </summary>
457459
/// <param name="writer">The writer.</param>
458-
private void AppendTags(StringBuilder writer)
460+
/// <param name="defaultTags">Tags added to point</param>
461+
private void AppendTags(StringBuilder writer, Dictionary<string, string>? defaultTags = null)
459462
{
460-
foreach (var name in _values.GetTagNames())
463+
var allNames = defaultTags == null
464+
? _values.GetTagNames()
465+
: _values.GetTagNames().Concat(defaultTags.Keys).ToArray()
466+
;
467+
Array.Sort(allNames);
468+
var lastName = "" == allNames.FirstOrDefault() ? "_" : "";
469+
470+
foreach (var name in allNames)
461471
{
462-
var value = _values.GetTag(name);
472+
if (name == lastName) continue;
473+
lastName = name;
474+
475+
var value = _values.GetTag(name)
476+
?? defaultTags.First(kv => kv.Key == name).Value;
463477

464478
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value))
465479
{

0 commit comments

Comments
 (0)