public override async Task WriteMessages(string database, IEnumerable<WriteMessage> messages, Consistency? consistency = null, string retentionPolicy = null, DateTime? timestamp = null, TimePrecision? precision = null)
 {
     using (var msg = new HttpRequestMessage(HttpMethod.Post, CreateUrl("/write", database, null, null, consistency, retentionPolicy)))
     {
         msg.Content = new StringContent(string.Join("\n", messages.Select(x => x.ToString(timestamp, precision))), Encoding.UTF8);
         using (var response = await _client.SendAsync(msg, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None).ConfigureAwait(false))
         {
             response.ValidateHttpResponse(HttpStatusCode.NoContent, true);
         }
     }
 }
        /// <summary>
        /// Tracks an event.
        /// </summary>
        /// <param name="category">
        /// Typically the object that was interacted with (e.g. button)
        /// </param>
        /// <param name="action">
        /// The type of interaction (e.g. click)
        /// </param>
        /// <param name="eventId">
        /// The id of the thing being interacted with.
        /// </param>
        /// <param name="precision">
        /// The precision that this event should be tracked at.
        /// </param>
        /// <param name="now">
        /// The now.
        /// </param>
        public static void TrackEvent(
            string category,
            string action,
            long eventId,
            TimePrecision precision = TimePrecision.OneDay,
            DateTime now = default(DateTime))
        {
            if (now == default(DateTime))
            {
                now = DateTime.UtcNow;
            }

            string time;
            switch (precision)
            {
                case TimePrecision.FifteenMinutes:
                {
                    time = DateTimeUtil.FifteenMinutes(now);
                    break;
                }

                case TimePrecision.OneHour:
                {
                    time = DateTimeUtil.OneHour(now);
                    break;
                }

                case TimePrecision.OneDay:
                {
                    time = DateTimeUtil.OneDay(now);
                    break;
                }

                case TimePrecision.OneMonth:
                {
                    time = DateTimeUtil.OneMonth(now);
                    break;
                }

                default:
                {
                    throw new Exception(string.Format("unsupported precision encountered\n\t{0}", precision));
                }
            }

            RedisKey key = EventKey(category, action, time);

            SharedCache.Instance.GetAnalyticsWriteConnection()
                .GetDatabase(SharedCache.Instance.Db)
                .StringSetBit(key, eventId, true);
        }
 public static long ToEpoch(this DateTime time, TimePrecision precision)
 {
     TimeSpan t = time - Origin;
     switch ( precision )
     {
         case TimePrecision.Hours: return (long) t.TotalHours;
         case TimePrecision.Minutes: return (long) t.TotalMinutes;
         case TimePrecision.Seconds: return (long) t.TotalSeconds;
         case TimePrecision.Milliseconds: return (long) t.TotalMilliseconds;
         case TimePrecision.Microseconds: return (long) t.TotalMilliseconds * 1000;
         case TimePrecision.Nanoseconds: return (long) t.TotalMilliseconds * 1000 * 1000;
     }
     return 0;
 }
        public override async Task<ResultSet> SendQuery(string database, string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = default(CancellationToken))
        {
            using (var message = new HttpRequestMessage(HttpMethod.Post, CreateUrl("/query", database, query)))
            using (var response = await _client.SendAsync(message, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false))
            {
                response.ValidateHttpResponse(HttpStatusCode.OK, false);

                var result = await response.Content
                    .ReadAsAsync<ResultSet>(cancellationToken)
                    .ConfigureAwait(false);

                return result;
            }
        }
 public static DateTime FromEpoch (this string time, TimePrecision precision)
 {
     long duration = long.Parse (time);
     DateTime t = Origin;
     switch (precision)
     {
         case TimePrecision.Hours: return t.AddHours (duration);
         case TimePrecision.Minutes: return t.AddMinutes (duration);
         case TimePrecision.Seconds: return t.AddSeconds (duration);
         case TimePrecision.Milliseconds: return t.AddMilliseconds (duration);
         case TimePrecision.Microseconds: return t.AddTicks (duration * TimeSpan.TicksPerMillisecond * 1000);
         case TimePrecision.Nanoseconds: return t.AddTicks (duration / 100); //1 tick = 100 nano sec
     }
     return t;
 }
 public AdaptiveTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
     switch (precision)
     {
         case TimePrecision.Nanosecond:
         case TimePrecision.Microsecond:
             _generator = SystemTimePreciseTimestampSource.IsAvailable
                 ? (Func<DateTime>) GetSystemTimePrecise
                 : GetDateTimeStopwatch;
             break;
         default:
             _generator = GetDateTime;
             break;
     }
 }
 public static long ToUnixTime(DateTime date, TimePrecision precision)
 {
     switch (precision)
     {
         case TimePrecision.Nanosecond:
             return Convert.ToInt64((date.ToUniversalTime() - Epoch).TotalNanoseconds());
         case TimePrecision.Microsecond:
             return Convert.ToInt64((date.ToUniversalTime() - Epoch).TotalMicroseconds());
         case TimePrecision.Millisecond:
             return Convert.ToInt64((date.ToUniversalTime() - Epoch).TotalMilliseconds);
         case TimePrecision.Second:
             return Convert.ToInt64((date.ToUniversalTime() - Epoch).TotalSeconds);
         case TimePrecision.Minute:
             return Convert.ToInt64((date.ToUniversalTime() - Epoch).TotalMinutes);
         case TimePrecision.Hour:
             return Convert.ToInt64((date.ToUniversalTime() - Epoch).TotalHours);
         default:
             throw new ArgumentException("Unsupported precision: " + precision, "precision");
     }
 }
        public static DateTime FromEpoch(this string time, TimePrecision precision)
        {
            long     duration = long.Parse(time);
            DateTime t        = Origin;

            switch (precision)
            {
            case TimePrecision.Hours: return(t.AddHours(duration));

            case TimePrecision.Minutes: return(t.AddMinutes(duration));

            case TimePrecision.Seconds: return(t.AddSeconds(duration));

            case TimePrecision.Milliseconds: return(t.AddMilliseconds(duration));

            case TimePrecision.Microseconds: return(t.AddTicks(duration * TimeSpan.TicksPerMillisecond * 1000));

            case TimePrecision.Nanoseconds: return(t.AddTicks(duration / 100));     //1 tick = 100 nano sec
            }
            return(t);
        }
Example #9
0
        /// <summary>
        /// Convert the Influx Series JSON objects to InfluxSeries
        /// </summary>
        /// <param name="precision"></param>
        /// <param name="series"></param>
        /// <param name="SafePropertyNames">If true the first letter of each property name will be Capital, making them safer to use in C#</param>
        /// <returns></returns>
        private static InfluxSeries GetInfluxSeries(TimePrecision precision, Series series, bool SafePropertyNames = true)
        {
            var result = new InfluxSeries()
            {
                HasEntries = false
            };

            result.SeriesName = series.Name;
            result.Tags       = series.Tags;
            var entries = new List <dynamic>();

            for (var row = 0; row < series?.Values?.Count; row++)
            {
                result.HasEntries = true;
                dynamic entry = new ExpandoObject();
                entries.Add(entry);
                for (var col = 0; col < series.Columns.Count; col++)
                {
                    string header;
                    if (SafePropertyNames)
                    {
                        header = char.ToUpper(series.Columns[col][0]) + series.Columns[col].Substring(1);
                    }
                    else
                    {
                        header = series.Columns[col];
                    }
                    if (String.Equals(header, "Time", StringComparison.OrdinalIgnoreCase))
                    {
                        ((IDictionary <string, object>)entry).Add(header, EpochHelper.FromEpoch(series.Values[row][col], precision));
                    }
                    else
                    {
                        ((IDictionary <string, object>)entry).Add(header, series.Values[row][col]);
                    }
                }
            }
            result.Entries = entries;
            return(result);
        }
Example #10
0
File: Time.cs Project: minskowl/MY
        /// <summary>
        /// Initializes a new instance of the <see cref="Time"/> struct.
        /// </summary>
        /// <param name="time">The time.</param>
        /// <param name="precision">The precision.</param>
        public Time(Time time, TimePrecision precision)
        {
            _precision = precision;
            switch (precision)
            {
            case TimePrecision.WithMilliseconds:
                _hour        = time.Hour;
                _minute      = time.Minute;
                _second      = time.Second;
                _millisecond = time.Millisecond;

                break;

            case TimePrecision.WithSeconds:
                _hour        = time.Hour;
                _minute      = time.Minute;
                _second      = time.Second;
                _millisecond = 0;

                break;

            case TimePrecision.WithMinutes:
                _hour        = time.Hour;
                _minute      = time.Minute;
                _second      = 0;
                _millisecond = 0;
                break;

            case TimePrecision.WithHours:
                _hour        = time.Hour;
                _minute      = 0;
                _second      = 0;
                _millisecond = 0;
                break;

            default:
                throw new ArgumentOutOfRangeException("precision");
            }
        }
        private async Task <bool> PostPointsAsync(string dbName, TimePrecision precision, IEnumerable <IInfluxDatapoint> points)
        {
            var influxAddress = new Uri(String.Format("{0}/write?", InfluxUrl));
            var builder       = new UriBuilder(influxAddress);

            builder.Query = await new FormUrlEncodedContent(new[] {
                new KeyValuePair <string, string>("db", dbName),
                new KeyValuePair <string, string>("precision", precisionLiterals[(int)precision])
            }).ReadAsStringAsync();

            var line = new StringBuilder();

            foreach (var point in points)
            {
                line.AppendFormat("{0}\n", point.ConvertToInfluxLineProtocol());
            }
            //remove last \n
            line.Remove(line.Length - 1, 1);

            ByteArrayContent    requestContent = new ByteArrayContent(Encoding.UTF8.GetBytes(line.ToString()));
            HttpResponseMessage response       = await PostAsync(builder, requestContent);

            if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.BadGateway || (response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "INKApi Error"))     //502 Connection refused
            {
                throw new UnauthorizedAccessException("InfluxDB needs authentication. Check uname, pwd parameters");
            }
            //if(response.StatusCode==HttpStatusCode.NotFound)
            else if (response.StatusCode == HttpStatusCode.NoContent)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Posts raw write request to Influx.
        /// </summary>
        /// <param name="dbName">Name of the Database</param>
        /// <param name="precision">Unit of the timestamp, Hour->nanosecond</param>
        /// <param name="content">Raw request, as per Line Protocol</param>
        /// <see cref="https://influxdb.com/docs/v0.9/write_protocols/write_syntax.html#http"/>
        /// <returns>true:success, false:failure</returns>
        public async Task<bool> PostRawValueAsync (string dbName, TimePrecision precision, string content)
        {
            ByteArrayContent requestContent = new ByteArrayContent (Encoding.UTF8.GetBytes (content));
            HttpResponseMessage response = await PostAsync (new Dictionary<string, string> () { { "db", dbName }, { "precision", precisionLiterals[(int) precision] } }, requestContent);

            if (response.StatusCode == HttpStatusCode.NoContent)
                return true;
            else
                return false;
        }
Example #13
0
 /// <summary>
 /// 获取显示时间
 /// </summary>
 /// <param name="ticks"></param>
 /// <param name="precision">时间精度</param>
 /// <param name="includeDay">是否显示天数</param>
 /// <returns></returns>
 public static string GetTimeText(this long ticks, TimePrecision precision, bool includeDay = true)
 {
     return(TimeSpan.FromTicks(ticks).GetTimeText(precision, includeDay));
 }
        public List<Serie> Query(string query, TimePrecision? precision = null)
        {
            string escapedQuery = HttpUtility.UrlEncode(query);
            string url = this.GetUrl("/db/" + this.database + "/series");
            if (precision.HasValue)
            {
                url += "&time_precision=" + this.timePrecision[(int) precision.Value];
            }
            url += "&q=" + escapedQuery;
            object result = this.Request(url, "GET");

            if (result != null)
            {
                return JsonConvert.DeserializeObject<List<Serie>>(result.ToString());
            }

            return null;
        }
 public SequentialTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
 }
 public InfluxDBClient(string host, int port, bool useHttps, string username, string password, string database, Consistency defaultConsistency, TimePrecision timestampPrecision = TimePrecision.Nanosecond) : this(database, defaultConsistency)
 {
     RequestProcessor   = new HttpClientRequestProcessor(new RequestProcessorSettings(host, port, useHttps, username, password));
     TimestampGenerator = new AdaptiveTimestampGenerator(timestampPrecision);
 }
        /// <summary>
        /// Queries Influx DB and gets a time series data back. Ideal for fetching measurement values.
        /// The return list is of InfluxSeries, and each element in there will have properties named after columns in series
        /// </summary>
        /// <param name="dbName">Name of the database</param>
        /// <param name="measurementQuery">Query text, Only results with single series are supported for now</param>
        /// <param name="precision">epoch precision of the data set</param>
        /// <returns>List of InfluxSeries</returns>
        /// <seealso cref="InfluxSeries"/>
        public async Task<List<IInfluxSeries>> QueryMultiSeriesAsync (string dbName, string measurementQuery, TimePrecision precision = TimePrecision.Nanoseconds)
        {
            var response = await GetAsync (new Dictionary<string, string> () { { "db", dbName }, { "q", measurementQuery }, { "epoch", precisionLiterals[(int) precision] } });
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var results = new List<IInfluxSeries> ();
                var rawResult = JsonConvert.DeserializeObject<InfluxResponse> (await response.Content.ReadAsStringAsync ());

                if (rawResult?.Results?.Count > 1)
                    throw new ArgumentException ("The query is resulting in a format, which is not supported by this method yet");

                if (rawResult?.Results[0]?.Series != null)
                {
                    foreach (var series in rawResult?.Results[0]?.Series)
                    {
                        var result = new InfluxSeries ();
                        result.HasEntries = false;
                        results.Add (result);
                        result.SeriesName = series.Name;
                        result.Tags = series.Tags;
                        var entries = new List<dynamic> ();
                        for (var row = 0; row < series?.Values?.Count; row++)
                        {
                            result.HasEntries = true;
                            dynamic entry = new ExpandoObject ();
                            entries.Add (entry);
                            for (var col = 0; col < series.Columns.Count; col++)
                            {
                                var header = char.ToUpper (series.Columns[col][0]) + series.Columns[col].Substring (1);

                                if (header == "Time")
                                    ((IDictionary<string, object>) entry).Add (header, EpochHelper.FromEpoch (series.Values[row][col], precision));
                                else
                                    ((IDictionary<string, object>) entry).Add (header, series.Values[row][col]);
                            }
                        }
                        result.Entries = entries;
                    }
                }
                return results;
            }
            return null;
        }
Example #18
0
 public TimePrecisionAttribute(TimePrecision precision)
     : base((byte)precision)
 {
     Precision = precision;
 }
 public InfluxTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
 }
        public async Task <bool> PostValuesAsync(string dbName, string measurement, long timestamp, TimePrecision precision, string tags, IDictionary <string, double> values)
        {
            var influxAddress = new Uri(String.Format("{0}/write?", InfluxUrl));
            var builder       = new UriBuilder(influxAddress);

            builder.Query = await new FormUrlEncodedContent(new[] {
                new KeyValuePair <string, string>("db", dbName),
                new KeyValuePair <string, string>("precision", precisionLiterals[(int)precision])
            }).ReadAsStringAsync();

            //var content = new StringBuilder ();
            //foreach ( var value in values )
            //    content.AppendFormat ("{0},{1} {2} {3}\n", measurement, tags, value, timestamp);
            ////remove last \n
            //content.Remove (content.Length - 1, 1);
            var valuesTxt = String.Join(",", values.Select(v => String.Format(System.Globalization.CultureInfo.GetCultureInfo("en-US"), "{0}={1}", v.Key, v.Value)));
            var content   = String.Format("{0},{1} {2} {3}", measurement, tags, valuesTxt, timestamp);

            ByteArrayContent    requestContent = new ByteArrayContent(Encoding.UTF8.GetBytes(content.ToString()));
            HttpResponseMessage response       = await PostAsync(builder, requestContent);

            if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.BadGateway || (response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "INKApi Error"))     //502 Connection refused
            {
                throw new UnauthorizedAccessException("InfluxDB needs authentication. Check uname, pwd parameters");
            }
            //if(response.StatusCode==HttpStatusCode.NotFound)

            else if (response.StatusCode == HttpStatusCode.NoContent)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
 public DateTimeStopwatchTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
 }
 public InfluxDBClient(string host, int port, bool useHttps, string username, string password, string database, Consistency defaultConsistency, TimePrecision timestampPrecision = TimePrecision.Nanosecond) : this(database, defaultConsistency)
 {
     RequestProcessor = new HttpClientRequestProcessor(new RequestProcessorSettings(host, port, useHttps, username, password));
     TimestampGenerator = new AdaptiveTimestampGenerator(timestampPrecision);
 }
Example #23
0
 public string ToString(DateTime? timestamp, TimePrecision? precision, double comparisonTolerance = 0.00001)
 {
     return Key + " " + Fields.FormatFields(comparisonTolerance) + (timestamp.HasValue ? " " + ToUnixTime(timestamp.Value, (precision ?? TimePrecision.Nanosecond)) : string.Empty);
 }
Example #24
0
        /// <summary>
        /// Queries Influx DB and gets a time series data back. Ideal for fetching measurement values.
        /// The return list is of InfluxSeries, and each element in there will have properties named after columns in series
        /// THis uses Chunking support from InfluxDB. It returns results in streamed batches rather than as a single response
        /// Responses will be chunked by series or by every ChunkSize points, whichever occurs first.
        /// </summary>
        /// <param name="dbName">Name of the database</param>
        /// <param name="measurementQuery">Query text, Only results with single series are supported for now</param>
        /// <param name="ChunkSize">Maximum Number of points in a chunk</param>
        /// <param name="precision">epoch precision of the data set</param>
        /// <returns>List of InfluxSeries</returns>
        /// <seealso cref="InfluxSeries"/>
        public async Task <List <IInfluxSeries> > QueryMultiSeriesAsync(string dbName, string measurementQuery, int ChunkSize, TimePrecision precision = TimePrecision.Nanoseconds)
        {
            var response = await GetAsync(new Dictionary <string, string>() {
                { "db", dbName },
                { "q", measurementQuery },
                { "chunked", "true" },
                { "chunk_size", ChunkSize.ToString() },
                { "epoch", precisionLiterals[(int)precision] }
            });

            if (response == null)
            {
                throw new ServiceUnavailableException();
            }
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var results = new List <IInfluxSeries>();
                //Hack for https://github.com/influxdata/influxdb/issues/8212
                foreach (var str in (await response.Content.ReadAsStringAsync()).Split('\n'))
                {
                    var rawResult = JsonConvert.DeserializeObject <InfluxResponse>(str);
                    if (rawResult?.Results[0]?.Series != null)
                    {
                        foreach (var series in rawResult?.Results[0]?.Series)
                        {
                            InfluxSeries result = GetInfluxSeries(precision, series);
                            results.Add(result);
                        }
                    }
                    if (!rawResult.Results[0].Partial)
                    {
                        break;
                    }
                }

                return(results);
            }
            return(null);
        }
Example #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TimeRange"/> struct.
 /// </summary>
 /// <param name="range">The range.</param>
 /// <param name="precision">The precision.</param>
 public TimeRange(TimeRange range, TimePrecision precision)
 {
     from = new Time(range.From, precision);
     to   = new Time(range.To, precision);
 }
        /// <summary>
        /// Posts raw write request to Influx.
        /// </summary>
        /// <param name="dbName">Name of the Database</param>
        /// <param name="precision">Unit of the timestamp, Hour->nanosecond</param>
        /// <param name="content">Raw request, as per Line Protocol</param>
        /// <see cref="https://influxdb.com/docs/v0.9/write_protocols/write_syntax.html#http"/>
        /// <returns>true:success, false:failure</returns>
        public async Task<bool> PostRawValueAsync(string dbName, TimePrecision precision, string content)
        {
            var influxAddress = new Uri (String.Format ("{0}/write?", InfluxUrl));
            var builder = new UriBuilder (influxAddress);
            builder.Query = await new FormUrlEncodedContent (new[] { 
                    new KeyValuePair<string, string>("db", dbName) ,
                    new KeyValuePair<string, string>("precision", precisionLiterals[(int) precision])
                    }).ReadAsStringAsync ();


            ByteArrayContent requestContent = new ByteArrayContent (Encoding.UTF8.GetBytes (content));
            HttpResponseMessage response = await PostAsync (builder, requestContent);

            if ( response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.BadGateway || ( response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "INKApi Error" ) ) //502 Connection refused
                throw new UnauthorizedAccessException ("InfluxDB needs authentication. Check uname, pwd parameters");
            //if(response.StatusCode==HttpStatusCode.NotFound)

            else if ( response.StatusCode == HttpStatusCode.NoContent )
                return true;
            else
                return false;
        }
 public Task <ResultSet> SendQuery(string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = new CancellationToken())
 {
     return(SendQuery(null, query, resultPrecision, cancellationToken));
 }
        public async Task<bool> PostValuesAsync(string dbName, string measurement, long timestamp, TimePrecision precision, string tags, IDictionary<string, double> values)
        {
            var influxAddress = new Uri (String.Format ("{0}/write?", InfluxUrl));
            var builder = new UriBuilder (influxAddress);
            builder.Query = await new FormUrlEncodedContent (new[] { 
                    new KeyValuePair<string, string>("db", dbName) ,
                    new KeyValuePair<string, string>("precision", precisionLiterals[(int) precision])
                    }).ReadAsStringAsync ();

            //var content = new StringBuilder ();
            //foreach ( var value in values )
            //    content.AppendFormat ("{0},{1} {2} {3}\n", measurement, tags, value, timestamp);
            ////remove last \n
            //content.Remove (content.Length - 1, 1);
            var valuesTxt = String.Join (",", values.Select (v => String.Format (System.Globalization.CultureInfo.GetCultureInfo ("en-US"), "{0}={1}", v.Key, v.Value)));
            var content = String.Format ("{0},{1} {2} {3}", measurement, tags, valuesTxt, timestamp);

            ByteArrayContent requestContent = new ByteArrayContent (Encoding.UTF8.GetBytes (content.ToString ()));
            HttpResponseMessage response = await PostAsync (builder, requestContent);

            if ( response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.BadGateway || ( response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "INKApi Error" ) ) //502 Connection refused
                throw new UnauthorizedAccessException ("InfluxDB needs authentication. Check uname, pwd parameters");
            //if(response.StatusCode==HttpStatusCode.NotFound)

            else if ( response.StatusCode == HttpStatusCode.NoContent )
                return true;
            else
                return false;
        }
        public override async Task <ResultSet> SendQuery(string database, string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = default(CancellationToken))
        {
            using (var message = new HttpRequestMessage(HttpMethod.Post, CreateUrl("/query", database, query)))
                using (var response = await _client.SendAsync(message, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false))
                {
                    response.ValidateHttpResponse(HttpStatusCode.OK, false);

                    var result = await response.Content
                                 .ReadAsAsync <ResultSet>(cancellationToken)
                                 .ConfigureAwait(false);

                    return(result);
                }
        }
 public abstract Task <ResultSet> SendQuery(string database, string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = new CancellationToken());
Example #31
0
        /// <summary>
        /// Queries Influx DB and gets a time series data back. Ideal for fetching measurement values.
        /// The return list is of InfluxSeries, and each element in there will have properties named after columns in series
        /// </summary>
        /// <param name="dbName">Name of the database</param>
        /// <param name="measurementQuery">Query text, Only results with single series are supported for now</param>
        /// <param name="precision">epoch precision of the data set</param>
        /// <returns>List of InfluxSeries</returns>
        /// <seealso cref="InfluxSeries"/>
        public async Task <List <IInfluxSeries> > QueryMultiSeriesAsync(string dbName, string measurementQuery, TimePrecision precision = TimePrecision.Nanoseconds)
        {
            var response = await GetAsync(new Dictionary <string, string>() { { "db", dbName }, { "q", measurementQuery }, { "epoch", precisionLiterals[(int)precision] } });

            if (response == null)
            {
                throw new ServiceUnavailableException();
            }
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var results   = new List <IInfluxSeries>();
                var rawResult = JsonConvert.DeserializeObject <InfluxResponse>(await response.Content.ReadAsStringAsync());

                if (rawResult?.Results?.Count > 1)
                {
                    throw new ArgumentException("The query is resulting in a format, which is not supported by this method yet");
                }

                if (rawResult?.Results[0]?.Series != null)
                {
                    foreach (var series in rawResult?.Results[0]?.Series)
                    {
                        InfluxSeries result = GetInfluxSeries(precision, series);
                        results.Add(result);
                    }
                }
                return(results);
            }
            return(null);
        }
Example #32
0
        public static string HumanReadableDateDiff(DateTime MainDate, DateTime OtherDate, TimePrecision Precision, TimePrecision MaxFallBackPrecision, string Separator, bool WriteSuffix)
        {
            string functionReturnValue = null;

            functionReturnValue = "";

            int years        = 0;
            int months       = 0;
            int days         = 0;
            int hours        = 0;
            int minutes      = 0;
            int seconds      = 0;
            int milliseconds = 0;

            string S_year         = "year";
            string S_month        = "month";
            string S_day          = "day";
            string S_hour         = "hour";
            string S_minute       = "min";
            string S_second       = "sec";
            string S_millisecond  = "ms";
            string S_years        = "years";
            string S_months       = "months";
            string S_days         = "days";
            string S_hours        = "hours";
            string S_minutes      = "min";
            string S_seconds      = "sec";
            string S_milliseconds = "ms";
            string S_now          = "now";
            string S_ago          = "ago";


            DateTime BiggerDate   = default(DateTime);
            DateTime SmallestDate = default(DateTime);

            if (MainDate.CompareTo(OtherDate) >= 0)
            {
                BiggerDate   = MainDate;
                SmallestDate = OtherDate;
            }
            else
            {
                BiggerDate   = OtherDate;
                SmallestDate = MainDate;
            }


            while ((BiggerDate.AddYears(-1).CompareTo(SmallestDate) >= 0))
            {
                years     += 1;
                BiggerDate = BiggerDate.AddYears(-1);
            }

            while ((BiggerDate.AddMonths(-1).CompareTo(SmallestDate) >= 0))
            {
                months    += 1;
                BiggerDate = BiggerDate.AddMonths(-1);
            }

            while ((BiggerDate.AddDays(-1).CompareTo(SmallestDate) >= 0))
            {
                days      += 1;
                BiggerDate = BiggerDate.AddDays(-1);
            }

            TimeSpan diff = BiggerDate.Subtract(SmallestDate);

            hours        = diff.Hours;
            minutes      = diff.Minutes;
            seconds      = diff.Seconds;
            milliseconds = diff.Milliseconds;


            //precision fallback
            if ((Precision == TimePrecision.Years) && (MaxFallBackPrecision > TimePrecision.Years) && (years == 0))
            {
                Precision = TimePrecision.Month;
            }
            if ((Precision == TimePrecision.Month) && (MaxFallBackPrecision > TimePrecision.Month) && (years == 0) && (months == 0))
            {
                Precision = TimePrecision.Day;
            }
            if ((Precision == TimePrecision.Day) && (MaxFallBackPrecision > TimePrecision.Day) && (years == 0) && (months == 0) && (days == 0))
            {
                Precision = TimePrecision.Hour;
            }
            if ((Precision == TimePrecision.Hour) && (MaxFallBackPrecision > TimePrecision.Hour) && (years == 0) && (months == 0) && (days == 0) && (hours == 0))
            {
                Precision = TimePrecision.Minute;
            }
            if ((Precision == TimePrecision.Minute) && (MaxFallBackPrecision > TimePrecision.Minute) && (years == 0) && (months == 0) && (days == 0) && (hours == 0) && (minutes == 0))
            {
                Precision = TimePrecision.Second;
            }
            if ((Precision == TimePrecision.Second) && (MaxFallBackPrecision > TimePrecision.Second) && (years == 0) && (months == 0) && (days == 0) && (hours == 0) && (minutes == 0) && (seconds == 0))
            {
                Precision = TimePrecision.Millisecond;
            }


            if (years > 0)
            {
                functionReturnValue += string.Format("{0} {1}|", years, (years == 1 ? S_year : S_years));
            }
            if (Precision > TimePrecision.Years && months > 0)
            {
                functionReturnValue += string.Format("{0} {1}|", months, (months == 1 ? S_month : S_months));
            }
            if (Precision > TimePrecision.Month && days > 0)
            {
                functionReturnValue += string.Format("{0} {1}|", days, (days == 1 ? S_day : S_days));
            }
            if (Precision > TimePrecision.Day && hours > 0)
            {
                functionReturnValue += string.Format("{0} {1}|", hours, (hours == 1 ? S_hour : S_hours));
            }
            if (Precision > TimePrecision.Hour && minutes > 0)
            {
                functionReturnValue += string.Format("{0} {1}|", minutes, (minutes == 1 ? S_minute : S_minutes));
            }
            if (Precision > TimePrecision.Minute && seconds > 0)
            {
                functionReturnValue += string.Format("{0} {1}|", seconds, (seconds == 1 ? S_second : S_seconds));
            }
            if (Precision > TimePrecision.Second && milliseconds > 0)
            {
                functionReturnValue += string.Format("{0} {1}|", milliseconds, (milliseconds == 1 ? S_millisecond : S_milliseconds));
            }

            if (functionReturnValue == null || string.IsNullOrEmpty(functionReturnValue))
            {
                if (WriteSuffix)
                {
                    functionReturnValue = S_now;
                }
            }
            else
            {
                functionReturnValue = functionReturnValue.Trim(new char[] { '|' });
                functionReturnValue = functionReturnValue.Replace("|", Separator);

                if (WriteSuffix)
                {
                    if (MainDate.CompareTo(OtherDate) > 0)
                    {
                        functionReturnValue = functionReturnValue + " " + S_ago;
                    }
                }
            }
            return(functionReturnValue);
        }
Example #33
0
 /// <summary>
 /// Initializes a time control
 /// </summary>
 public TimeControl(uint targetFPS, TimePrecision precision)
 {
     TargetFPS = targetFPS; Precision = precision;
 }
Example #34
0
 public DateTimeStopwatchTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
 }
 public async Task <ResultSet> Query(string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(await RequestProcessor.SendQuery(query, resultPrecision, cancellationToken).ConfigureAwait(false));
 }
 public async Task<ResultSet> Query(string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = default(CancellationToken))
 {
     return await RequestProcessor.SendQuery(query, resultPrecision, cancellationToken).ConfigureAwait(false);
 }
 public Task<ResultSet> SendQuery(string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = new CancellationToken())
 {
     return SendQuery(null, query, resultPrecision, cancellationToken);
 }
Example #38
0
 public static string TimeSpanToString(TimeSpan Span, TimePrecision Precision, TimePrecision MaxFallBackPrecision, string Separator, bool WriteSuffix)
 {
     if (Span >= TimeSpan.MaxValue)
     {
         return("+∞");
     }
     else if (Span <= TimeSpan.MinValue)
     {
         return("-∞");
     }
     else
     {
         DateTime N = DateTime.Now;
         return(HumanReadableDateDiff(N, N.Add(Span), Precision, MaxFallBackPrecision, Separator, WriteSuffix));
     }
 }
 public abstract Task<ResultSet> SendQuery(string database, string query, TimePrecision resultPrecision = TimePrecision.Microsecond, CancellationToken cancellationToken = new CancellationToken());
 public abstract Task WriteMessage(string database, WriteMessage message, Consistency? consistency = null, string retentionPolicy = null, DateTime? timestamp = null, TimePrecision? precision = null);
 public abstract Task WriteMessages(string database, IEnumerable<WriteMessage> messages, Consistency? consistency = null, string retentionPolicy = null, DateTime? timestamp = null, TimePrecision? precision = null);
 public SystemTimePreciseTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
 }
        protected string CreateUrl(string path, string database = null, string query = null, TimePrecision? timePrecision = null, Consistency? consistency = null, string retentionPolicy = null, TimePrecision? resultPrecision = null)
        {
            var queryString = new StringBuilder("?");

            if (!string.IsNullOrEmpty(query))
            {
                queryString.Append("q=" + Uri.EscapeDataString(query.StripWhitespace()) + "&");
            }

            if (!string.IsNullOrEmpty(database))
            {
                queryString.Append("db=" + Uri.EscapeDataString(database.FormatIdentifier()) + "&");
            }

            if (retentionPolicy != null)
            {
                queryString.Append("rp=" + Uri.EscapeDataString(retentionPolicy.FormatIdentifier()) + "&");
            }

            if (!string.IsNullOrEmpty(Settings.Username) && !string.IsNullOrEmpty(Settings.Password))
            {
                queryString.Append("u=" + Uri.EscapeDataString(Settings.Username.Trim()) + "&");
                queryString.Append("p=" + Uri.EscapeDataString(Settings.Password.Trim()) + "&");
            }

            if (timePrecision.HasValue)
            {
                switch (timePrecision)
                {
                    case TimePrecision.Nanosecond:
                        // This is the default precision
                        queryString.Append("precision=n&");
                        break;
                    case TimePrecision.Microsecond:
                        queryString.Append("precision=u&");
                        break;
                    case TimePrecision.Millisecond:
                        queryString.Append("precision=ms&");
                        break;
                    case TimePrecision.Second:
                        queryString.Append("precision=s&");
                        break;
                    case TimePrecision.Minute:
                        queryString.Append("precision=m&");
                        break;
                    case TimePrecision.Hour:
                        queryString.Append("precision=h&");
                        break;
                }
            }

            if (consistency.HasValue)
            {
                switch (consistency)
                {
                    case Consistency.One:
                        queryString.Append("consistency=one&");
                        break;
                    case Consistency.Quorum:
                        queryString.Append("consistency=quorum&");
                        break;
                    case Consistency.All:
                        queryString.Append("consistency=all&");
                        break;
                    case Consistency.Any:
                        queryString.Append("consistency=any&");
                        break;
                }
            }

            if (resultPrecision.HasValue)
            {
                switch (resultPrecision.Value)
                {
                    case TimePrecision.Nanosecond:
                        // This is the default precision
                        queryString.Append("epoch=n&");
                        break;
                    case TimePrecision.Microsecond:
                        queryString.Append("epoch=u&");
                        break;
                    case TimePrecision.Millisecond:
                        queryString.Append("epoch=ms&");
                        break;
                    case TimePrecision.Second:
                        queryString.Append("epoch=s&");
                        break;
                    case TimePrecision.Minute:
                        queryString.Append("epoch=m&");
                        break;
                    case TimePrecision.Hour:
                        queryString.Append("epoch=h&");
                        break;
                }
            }

            if (queryString.Length > 1)
            {
                queryString.Length -= 1;
            }
            else
            {
                queryString.Length = 0;
            }

            return string.Format("{0}://{1}:{2}{3}{4}",
                Settings.UseHttps ? "https" : "http",
                Settings.Host,
                Settings.Port,
                path.StartsWith("/") ? path : "/" + path,
                queryString);
        }
Example #44
0
        private async Task <bool> PostPointsAsync(string dbName, TimePrecision precision, string retention, IEnumerable <IInfluxDatapoint> points)
        {
            Regex multiLinePattern = new Regex(@"([\P{Cc}].*?) '([\P{Cc}].*?)':([\P{Cc}].*?)\\n", RegexOptions.Compiled, TimeSpan.FromSeconds(5));
            Regex oneLinePattern   = new Regex(@"{\""error"":""([9\P{Cc}]+) '([\P{Cc}]+)':([a-zA-Z0-9 ]+)", RegexOptions.Compiled, TimeSpan.FromSeconds(5));

            var line = new StringBuilder();

            foreach (var point in points)
            {
                line.AppendFormat("{0}\n", point.ConvertToInfluxLineProtocol());
            }
            //remove last \n
            line.Remove(line.Length - 1, 1);

            ByteArrayContent requestContent = new ByteArrayContent(Encoding.UTF8.GetBytes(line.ToString()));
            var endPoint = new Dictionary <string, string>()
            {
                { "db", dbName }
            };

            if (precision > 0)
            {
                endPoint.Add("precision", precisionLiterals[(int)precision]);
            }

            if (!String.IsNullOrWhiteSpace(retention))
            {
                endPoint.Add("rp", retention);
            }
            HttpResponseMessage response = await PostAsync(endPoint, requestContent);

            if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.BadGateway || (response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "INKApi Error")) //502 Connection refused
            {
                throw new UnauthorizedAccessException("InfluxDB needs authentication. Check uname, pwd parameters");
            }
            //if(response.StatusCode==HttpStatusCode.NotFound)
            else if (response.StatusCode == HttpStatusCode.BadRequest)
            {
                var content = await response.Content.ReadAsStringAsync();

                //regex assumes error text from https://github.com/influxdata/influxdb/blob/master/models/points.go ParsePointsWithPrecision
                //fmt.Sprintf("'%s': %v", string(block[start:len(block)])
                List <string> parts = null; string l = "";

                if (content.Contains("partial write"))
                {
                    try
                    {
                        if (content.Contains("\\n"))
                        {
                            parts = multiLinePattern.Matches(content.Substring(content.IndexOf("partial write:\\n") + 16)).ToList();
                        }
                        else
                        {
                            parts = oneLinePattern.Matches(content.Substring(content.IndexOf("partial write:\\n") + 16)).ToList();
                        }

                        if (parts.Count == 0)
                        {
                            throw new InfluxDBException("Partial Write", new Regex(@"\""error\"":\""(.*?)\""").Match(content).Groups[1].Value);
                        }

                        if (parts[1].Contains("\\n"))
                        {
                            l = parts[1].Substring(0, parts[1].IndexOf("\\n")).Unescape();
                        }
                        else
                        {
                            l = parts[1].Unescape();
                        }
                    }
                    catch (InfluxDBException e)
                    {
                        throw e;
                    }
                    catch (Exception)
                    {
                    }

                    var point = points.Where(p => p.ConvertToInfluxLineProtocol() == l).FirstOrDefault();
                    if (point != null)
                    {
                        throw new InfluxDBException("Partial Write", $"Partial Write : {parts?[0]} due to {parts?[2]}", point);
                    }
                    else
                    {
                        throw new InfluxDBException("Partial Write", $"Partial Write : {parts?[0]} due to {parts?[2]}", l);
                    }
                }
                else
                {
                    throw InfluxDBException.ProcessInfluxDBError(content);
                }
            }
            else if (response.StatusCode == HttpStatusCode.NoContent)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #45
0
 /// <summary>
 /// Toes the time.
 /// </summary>
 /// <param name="date">The date.</param>
 /// <param name="precision">The precision.</param>
 /// <returns></returns>
 public static Time ToTime(this DateTime date, TimePrecision precision)
 {
     return(new Time(date, precision));
 }
Example #46
0
        /// <summary>
        /// Queries Influx DB and gets a time series data back. Ideal for fetching measurement values.
        /// The return list is of InfluxSeries, and each element in there will have properties named after columns in series
        /// THis uses Chunking support from InfluxDB. It returns results in streamed batches rather than as a single response
        /// Responses will be chunked by series or by every ChunkSize points, whichever occurs first.
        /// </summary>
        /// <param name="dbName">Name of the database</param>
        /// <param name="measurementQuery">Query text, Only results with single series are supported for now</param>
        /// <param name="ChunkSize">Maximum Number of points in a chunk</param>
        /// <param name="precision">epoch precision of the data set</param>
        /// <returns>List of InfluxSeries</returns>
        /// <seealso cref="InfluxSeries"/>
        public async Task <List <IInfluxSeries> > QueryMultiSeriesAsync(string dbName, string measurementQuery, int ChunkSize, TimePrecision precision = TimePrecision.Nanoseconds)
        {
            var response = await GetAsync(new Dictionary <string, string>() {
                { "db", dbName },
                { "q", measurementQuery },
                { "chunked", "true" },
                { "chunk_size", ChunkSize.ToString() },
                { "epoch", precisionLiterals[(int)precision] }
            }, HttpCompletionOption.ResponseHeadersRead);

            if (response == null)
            {
                throw new ServiceUnavailableException();
            }
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var results = new List <IInfluxSeries>();

                var stream = await response.Content.ReadAsStreamAsync();

                using (var reader = new StreamReader(stream))
                {
                    do
                    {
                        var str = await reader.ReadLineAsync();

                        var rawResult = JsonConvert.DeserializeObject <InfluxResponse>(str);
                        if (rawResult?.Results[0]?.Series != null)
                        {
                            foreach (var series in rawResult?.Results[0]?.Series)
                            {
                                InfluxSeries result = GetInfluxSeries(precision, series);
                                results.Add(result);
                            }
                        }
                        if (!rawResult.Results[0].Partial)
                        {
                            break;
                        }
                    } while (!reader.EndOfStream);
                }
                return(results);
            }
            return(null);
        }
Example #47
0
 public InfluxTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
 }
 public SequentialTimestampGenerator(TimePrecision precision)
 {
     Precision = precision;
 }
Example #49
0
        /// <summary>
        /// Queries Influx DB and gets a time series data back. Ideal for fetching measurement values.
        /// The return list is of InfluxSeries, and each element in there will have properties named after columns in series
        /// </summary>
        /// <param name="dbName">Name of the database</param>
        /// <param name="measurementQuery">Query text, Only results with single series are supported for now</param>
        /// <param name="precision">epoch precision of the data set</param>
        /// <returns>List of InfluxSeries</returns>
        /// <seealso cref="InfluxSeries"/>
        public async Task <List <IInfluxSeries> > QueryMultiSeriesAsync(string dbName, string measurementQuery, TimePrecision precision = TimePrecision.Nanoseconds)
        {
            var response = await GetAsync(new Dictionary <string, string> () { { "db", dbName }, { "q", measurementQuery }, { "epoch", precisionLiterals[(int)precision] } });

            if (response.StatusCode == HttpStatusCode.OK)
            {
                var results   = new List <IInfluxSeries> ();
                var rawResult = JsonConvert.DeserializeObject <InfluxResponse> (await response.Content.ReadAsStringAsync());

                if (rawResult?.Results?.Count > 1)
                {
                    throw new ArgumentException("The query is resulting in a format, which is not supported by this method yet");
                }

                if (rawResult?.Results[0]?.Series != null)
                {
                    foreach (var series in rawResult?.Results[0]?.Series)
                    {
                        var result = new InfluxSeries();
                        result.HasEntries = false;
                        results.Add(result);
                        result.SeriesName = series.Name;
                        result.Tags       = series.Tags;
                        var entries = new List <dynamic> ();
                        for (var row = 0; row < series?.Values?.Count; row++)
                        {
                            result.HasEntries = true;
                            dynamic entry = new ExpandoObject();
                            entries.Add(entry);
                            for (var col = 0; col < series.Columns.Count; col++)
                            {
                                var header = char.ToUpper(series.Columns[col][0]) + series.Columns[col].Substring(1);

                                if (header == "Time")
                                {
                                    ((IDictionary <string, object>)entry).Add(header, EpochHelper.FromEpoch(series.Values[row][col], precision));
                                }
                                else
                                {
                                    ((IDictionary <string, object>)entry).Add(header, series.Values[row][col]);
                                }
                            }
                        }
                        result.Entries = entries;
                    }
                }
                return(results);
            }
            return(null);
        }
Example #50
0
        /// <summary>
        /// 获取显示时间
        /// </summary>
        /// <param name="ts"></param>
        /// <param name="precision">时间精度</param>
        /// <param name="includeDay">是否显示天数</param>
        /// <returns></returns>
        public static string GetTimeText(this TimeSpan ts, TimePrecision precision, bool includeDay = true)
        {
            var totalMilliseconds = ts.TotalMilliseconds;

            if (totalMilliseconds <= 0)
            {
                return(string.Empty);
            }

            var text = new List <string>();

            var totalSeconds       = (int)totalMilliseconds / MILLISECONDS_OF_SECOND;
            var remainMilliseconds = totalMilliseconds - totalSeconds * MILLISECONDS_OF_SECOND;

            var totalMinutes  = (int)totalSeconds / SECONDS_OF_MINUTE;
            var remainSeconds = totalSeconds - totalMinutes * SECONDS_OF_MINUTE;

            if (precision >= TimePrecision.Second)
            {
                if (remainMilliseconds > 0)
                {
                    text.Add(string.Format("{0}.{1}秒", remainSeconds, remainMilliseconds));
                }
                else if (remainSeconds > 0)
                {
                    text.Add(string.Format("{0}秒", remainSeconds));
                }
            }

            var totalHours    = (int)totalMinutes / MINUTES_OF_HOUR;
            var remainMinutes = totalMinutes - totalHours * MINUTES_OF_HOUR;

            if (precision >= TimePrecision.Minute)
            {
                if (remainMinutes > 0)
                {
                    text.Add(string.Format("{0}分", remainMinutes));
                }
            }

            var totalDays   = (int)totalHours / HOURS_OF_DAY;
            var remainHours = totalHours - totalDays * HOURS_OF_DAY;

            if (includeDay)
            {
                if (precision >= TimePrecision.Hour)
                {
                    if (remainHours > 0)
                    {
                        text.Add(string.Format("{0}小时", remainHours));
                    }
                }

                if (precision >= TimePrecision.Day)
                {
                    if (totalDays > 0)
                    {
                        text.Add(string.Format("{0}天", totalDays));
                    }
                }
            }
            else
            {
                if (precision >= TimePrecision.Hour)
                {
                    if (totalHours > 0)
                    {
                        text.Add(string.Format("{0}小时", totalHours));
                    }
                }
            }

            if (text.Any())
            {
                text.Reverse();
            }

            return(string.Join(string.Empty, text));
        }
        private async Task<bool> PostPointsAsync(string dbName, TimePrecision precision, IEnumerable<IInfluxDatapoint> points)
        {
            var influxAddress = new Uri (String.Format ("{0}/write?", InfluxUrl));
            var builder = new UriBuilder (influxAddress);
            builder.Query = await new FormUrlEncodedContent (new[] { 
                    new KeyValuePair<string, string>("db", dbName) ,
                    new KeyValuePair<string, string>("precision", precisionLiterals[(int) precision])
                    }).ReadAsStringAsync ();

            var line = new StringBuilder ();
            foreach ( var point in points )
                line.AppendFormat ("{0}\n", point.ConvertToInfluxLineProtocol ());
            //remove last \n
            line.Remove (line.Length - 1, 1);

            ByteArrayContent requestContent = new ByteArrayContent (Encoding.UTF8.GetBytes (line.ToString ()));
            HttpResponseMessage response = await PostAsync (builder, requestContent);

            if ( response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.BadGateway || ( response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "INKApi Error" ) ) //502 Connection refused
                throw new UnauthorizedAccessException ("InfluxDB needs authentication. Check uname, pwd parameters");
            //if(response.StatusCode==HttpStatusCode.NotFound)
            else if ( response.StatusCode == HttpStatusCode.BadRequest )
            {
                var content = await response.Content.ReadAsStringAsync ();
                //regex assumes error text from https://github.com/influxdata/influxdb/blob/master/models/points.go ParsePointsWithPrecision
                //fmt.Sprintf("'%s': %v", string(block[start:len(block)])
                List<string> parts; bool partialWrite;
                if ( content.Contains ("partial write") )
                {
                    if ( content.Contains ("\\n") )
                        parts = Regex.Matches (content.Substring (content.IndexOf ("partial write:\\n") + 16), @"([\P{Cc}].*?) '([\P{Cc}].*?)':([\P{Cc}].*?)\\n").ToList ();
                    else
                        parts = Regex.Matches (content.Substring (content.IndexOf ("partial write:\\n") + 16), @"([\P{Cc}].*?) '([\P{Cc}].*?)':([\P{Cc}].*?)").ToList ();
                    partialWrite = true;
                }
                else
                {
                    parts = Regex.Matches (content, @"{\""error"":""([9\P{Cc}]+) '([\P{Cc}]+)':([a-zA-Z0-9 ]+)").ToList ();
                    partialWrite = false;
                }
                string l;
                if ( parts[1].Contains ("\\n") )
                    l = parts[1].Substring (0, parts[1].IndexOf ("\\n")).Unescape ();
                else
                    l = parts[1].Unescape ();

                var point = points.Where (p => p.ConvertToInfluxLineProtocol () == l).FirstOrDefault ();
                if ( point != null )
                    throw new InfluxDBException (partialWrite ? "Partial Write" : "Failed to Write", String.Format ("{0}: {1} due to {2}", partialWrite ? "Partial Write" : "Failed to Write", parts[0], parts[2]), point);
                else
                    throw new InfluxDBException (partialWrite ? "Partial Write" : "Failed to Write", String.Format ("{0}: {1} due to {2}", partialWrite ? "Partial Write" : "Failed to Write", parts[0], parts[2]), l);
                return false;
            }
            else if ( response.StatusCode == HttpStatusCode.NoContent )
                return true;
            else
                return false;
        }
        public async Task TestPostPointsAsync_DifferentPrecisions()
        {
            try
            {
                var client = new InfluxDBClient(influxUrl, dbUName, dbpwd);
                var time   = DateTime.Now;
                var today  = DateTime.Now.ToShortDateString();
                var now    = DateTime.Now.ToShortTimeString();

                var points = new List <IInfluxDatapoint>();

                foreach (TimePrecision precision in Enum.GetValues(typeof(TimePrecision)))
                {
                    var point = new InfluxDatapoint <long>();
                    point.UtcTimestamp    = DateTime.UtcNow;
                    point.MeasurementName = $"Precision{precision.ToString()}";
                    point.Precision       = precision;
                    point.Tags.Add("Precision", precision.ToString());
                    point.Fields.Add("Ticks", point.UtcTimestamp.Ticks);
                    points.Add(point);
                }

                var r = await client.PostPointsAsync(dbName, points);

                Assert.IsTrue(r, "PostPointsAsync retunred false");

                var values = await client.QueryMultiSeriesAsync(dbName, "select * from /Precision[A-Za-z]s/");

                foreach (var val in values)
                {
                    var x = val?.Entries?.FirstOrDefault();
                    try
                    {
                        var           d = new DateTime(long.Parse(x.Ticks));
                        TimeSpan      t = d - x.Time;
                        TimePrecision p = Enum.Parse(typeof(TimePrecision), x.Precision);
                        switch (p)
                        {
                        case TimePrecision.Hours: Assert.IsTrue(t.TotalHours < 1); break;

                        case TimePrecision.Minutes: Assert.IsTrue(t.TotalMinutes < 1); break;

                        case TimePrecision.Seconds: Assert.IsTrue(t.TotalSeconds < 1); break;

                        case TimePrecision.Milliseconds: Assert.IsTrue(t.TotalMilliseconds < 1); break;

                        case TimePrecision.Microseconds: Assert.IsTrue(t.Ticks < (TimeSpan.TicksPerMillisecond / 1000)); break;

                        case TimePrecision.Nanoseconds: Assert.IsTrue(t.Ticks < 1); break;
                        }
                    }
                    catch (Exception e)
                    {
                    }
                }
            }
            catch (Exception e)
            {
                Assert.Fail($"Unexpected exception of type {e.GetType()} caught: {e.Message}");
                return;
            }
        }
        private async Task<bool> PostPointsAsync (string dbName, TimePrecision precision, string retention, IEnumerable<IInfluxDatapoint> points)
        {
            Regex multiLinePattern = new Regex (@"([\P{Cc}].*?) '([\P{Cc}].*?)':([\P{Cc}].*?)\\n", RegexOptions.Compiled, TimeSpan.FromSeconds (5));
            Regex oneLinePattern = new Regex (@"{\""error"":""([9\P{Cc}]+) '([\P{Cc}]+)':([a-zA-Z0-9 ]+)", RegexOptions.Compiled, TimeSpan.FromSeconds (5));

            var line = new StringBuilder ();
            foreach (var point in points)
                line.AppendFormat ("{0}\n", point.ConvertToInfluxLineProtocol ());
            //remove last \n
            line.Remove (line.Length - 1, 1);

            ByteArrayContent requestContent = new ByteArrayContent (Encoding.UTF8.GetBytes (line.ToString ()));
            var endPoint = new Dictionary<string, string> () {
                { "db", dbName },
                { "precision", precisionLiterals[(int)precision] } };
            if (!String.IsNullOrWhiteSpace (retention))
                endPoint.Add ("rp", retention);
            HttpResponseMessage response = await PostAsync (endPoint, requestContent);

            if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.BadGateway || (response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "INKApi Error")) //502 Connection refused
                throw new UnauthorizedAccessException ("InfluxDB needs authentication. Check uname, pwd parameters");
            //if(response.StatusCode==HttpStatusCode.NotFound)
            else if (response.StatusCode == HttpStatusCode.BadRequest)
            {
                var content = await response.Content.ReadAsStringAsync ();
                //regex assumes error text from https://github.com/influxdata/influxdb/blob/master/models/points.go ParsePointsWithPrecision
                //fmt.Sprintf("'%s': %v", string(block[start:len(block)])
                List<string> parts = null; string l = "";

                if (content.Contains ("partial write"))
                {
                    try
                    {
                        if (content.Contains ("\\n"))
                            parts = multiLinePattern.Matches (content.Substring (content.IndexOf ("partial write:\\n") + 16)).ToList ();
                        else
                            parts = oneLinePattern.Matches (content.Substring (content.IndexOf ("partial write:\\n") + 16)).ToList ();

                        if (parts[1].Contains ("\\n"))
                            l = parts[1].Substring (0, parts[1].IndexOf ("\\n")).Unescape ();
                        else
                            l = parts[1].Unescape ();
                    }
                    catch (Exception)
                    {

                    }

                    var point = points.Where (p => p.ConvertToInfluxLineProtocol () == l).FirstOrDefault ();
                    if (point != null)
                        throw new InfluxDBException ("Partial Write", $"Partial Write : {parts?[0]} due to {parts?[2]}", point);
                    else
                        throw new InfluxDBException ("Partial Write", $"Partial Write : {parts?[0]} due to {parts?[2]}", l);
                }
                else
                {
                    throw InfluxDBException.ProcessInfluxDBError (content);
                }
            }
            else if (response.StatusCode == HttpStatusCode.NoContent)
                return true;
            else
                return false;
        }