influxDB 0.9 C# 讀寫類
目前influxdb官網推薦的C#讀寫類是針對0.8版本的,截至本文寫作之前,尚未發現有針對0.9的讀寫類。
我使用influxdb的是用於保存服務器的運行數據,程序需要以windows service的形式運行。
influxdb提供了基於http的接口。一開始我使用的是httpClient來作為http客戶端,但是發現程序以windows serive的形式運行的時候,居然無法發起http請求!而當windows service附在其它進程上,或者以window form形式運行時,卻是正常的。試了多種方法,包括更改windows service的運行權限、更改.net的運行時版本、更換機器等,都不行,百思不行其解,說多了都是淚。園里的大大們,誰能告訴我為什么?最后只能將http客戶端換成WebClient。
回到正題,本讀寫類對influxdb提供的http api進行了封裝。目前實現了:
(1)讀數據。
(2)寫數據。包括批量寫入。
(3)身份認證。
代碼
核心類:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Net.Http;
7 using System.Security.Cryptography.X509Certificates;
8
9 public class InfluxDBClient
10 {
11 string _baseAddress;
12 string _username;
13 string _password;
14 16
17 /// <summary>
18 /// 構造函數
19 /// </summary>
20 /// <param name="baseAddress"></param>
21 /// <param name="username"></param>
22 /// <param name="password"></param>
23 public InfluxDBClient(string baseAddress, string username, string password)
24 {
25 this._baseAddress = baseAddress;
26 this._username = username;
27 this._password = password;
28 }
29
30
31
32 /// <summary>
33 /// 讀
34 /// </summary>
35 /// <param name="database"></param>
36 /// <param name="sql"></param>
37 /// <returns></returns>
38 public string Query(string database, string sql)
39 {
40 string pathAndQuery = string.Format("/query?db={0}&q={1}", database, sql);
41 string url = _baseAddress + pathAndQuery;
42
43 string result = HttpHelper.Get(url, _username, _password);
44 return result;
45 }
46
49
50
51
52 /// <summary>
53 /// 寫
54 /// </summary>
55 /// <param name="database"></param>
56 /// <param name="sql"></param>
57 /// <returns></returns>
58 public string Write(string database, string sql)
59 {
60 string pathAndQuery = string.Format("/write?db={0}&precision=s", database);
61 string url = _baseAddress + pathAndQuery;
62
63 string result = HttpHelper.Post(url, sql, _username, _password);
64 return result;
65 }
66 }
http幫助類
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Text;
6 using System.Threading.Tasks;
7
9 public class HttpHelper
10 {
13 /// <summary>
14 ///
15 /// </summary>
16 /// <param name="uri"></param>
17 /// <param name="username"></param>
18 /// <param name="password"></param>
19 /// <returns></returns>
20 public static string Get(string uri, string username, string password)
21 {
22 string result = string.Empty;
23
24 WebClient client = new WebClient();
25
26 if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
27 {
28 client.Credentials = GetCredentialCache(uri, username, password);
29 client.Headers.Add("Authorization", GetAuthorization(username, password));
30 }
31 return client.DownloadString(uri);
32 }
33
34
35
36
37 /// <summary>
38 ///
39 /// </summary>
40 /// <param name="uri"></param>
41 /// <param name="paramStr"></param>
42 /// <param name="username"></param>
43 /// <param name="password"></param>
44 /// <returns></returns>
45 public static string Post(string uri, string paramStr, string username, string password)
46 {
47 string result = string.Empty;
48
49 WebClient client = new WebClient();
50
51 // 采取POST方式必須加的Header
52 client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
53
54 byte[] postData = Encoding.UTF8.GetBytes(paramStr);
55
56 if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
57 {
58 client.Credentials = GetCredentialCache(uri, username, password);
59 client.Headers.Add("Authorization", GetAuthorization(username, password));
60 }
61
62 byte[] responseData = client.UploadData(uri, "POST", postData); // 得到返回字符流
63 return Encoding.UTF8.GetString(responseData);// 解碼
64 }
65
66
67
68
69
70
71 private static CredentialCache GetCredentialCache(string uri, string username, string password)
72 {
73 string authorization = string.Format("{0}:{1}", username, password);
74 CredentialCache credCache = new CredentialCache();
75 credCache.Add(new Uri(uri), "Basic", new NetworkCredential(username, password));
76 return credCache;
77 }
78
79
80
81
82 private static string GetAuthorization(string username, string password)
83 {
84 string authorization = string.Format("{0}:{1}", username, password);
85 return "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(authorization));
86 }
87
88
89
90 }
日期轉換的擴展方法
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7
8 public static class Extentions
9 {
10
11 /// <summary>
12 /// 將當前時間轉換成unix時間戳形式
13 /// </summary>
14 /// <param name="datetime"></param>
15 /// <returns></returns>
16 public static long ToUnixTimestamp(this DateTime datetime)
17 {
18 return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
19 }
20
21 }
注:influxdb的日期使用的是unix時間戳格式
使用方法
InfluxDBClient client = new InfluxDBClient("http://110.124.149.123:8086", username, password);
long timestamp = DateTime.Now.ToUnixTimestamp();
List<string> list = new List<string>();
list.Add(string.Format("requestsQueued value={0} {1}", 20, timestamp)); //requestsQueued為指標的名稱
list.Add(string.Format("currentConnections value={0} {1}", 10, timestamp));
list.Add(string.Format("bytesReceivedPerSec value={0} {1}", 100, timestamp));
string sql = string.Join("\n", list);
var result = client.Write("server01", sql);
需要進一步完善的地方
(1)目前讀取數據的時候,當前返回的是一個字符串,這只是body中的信息,而其http頭中還有部分信息。需要對這些信息進行封裝。
(2)在使用這個類的時候,需要對influxdb的讀寫語法有一定的了解。而理想狀態下,是不需要這樣的。比如寫數據,使用者只需要傳入一個鍵值對(指標,指標值),而不需要傳入類似於“requestsQueued value={0} {1}"這樣的包含了influxdb語法的字符串。
有興趣的同學可以對這個類進行改寫。
適用范圍
如果只是為了配合grafana來使用的話,這個讀寫類足夠了,因為grafana可以直接讀取influxdb的數據,我們要做的只是往influxdb中寫入數據。
參考資料
InfluxDB Docs v0.8 https://influxdb.com/docs/v0.8/introduction/overview.html
InfluxDB.Net https://github.com/ziyasal/InfluxDB.Net

