NTP Analyzer  0.8.2
Analyze the operation of time servers
TrafficGraph.cs
Go to the documentation of this file.
1 //
2 // Copyright (c) 2013-2017 Carsten Sonne Larsen <cs@innolan.net>
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 
22 using System;
23 using System.Collections.Generic;
24 using System.Drawing;
25 using System.Globalization;
26 using NPlot;
27 using Ntp.Analyzer.Data;
28 using Ntp.Analyzer.Data.Sql;
29 using Ntp.Analyzer.Interface;
30 using Ntp.Analyzer.Objects;
31 
32 namespace Ntp.Analyzer.Graph
33 {
34  public sealed class TrafficGraph : GraphBase
35  {
36  public TrafficGraph(ITrafficGraphConfiguration configuration, Host host)
37  : base(configuration)
38  {
39  config = configuration;
40  this.host = host;
41  }
42 
44  private readonly List<double> dropped = new List<double>();
45  private readonly List<double> droppedAvg = new List<double>();
46  private readonly Host host;
47  private readonly List<double> ignored = new List<double>();
48  private readonly List<double> ignoredAvg = new List<double>();
49  private readonly List<double> notSent = new List<double>();
50  private readonly List<double> notSentAvg = new List<double>();
51  private readonly List<double> received = new List<double>();
52  private readonly List<double> receivedAvg = new List<double>();
53  private readonly List<double> receivedAvgTot = new List<double>();
54  private readonly List<double> sent = new List<double>();
55  private readonly List<double> sentAvg = new List<double>();
56  private readonly List<DateTime> time = new List<DateTime>();
57 
58  protected override string YLabel
59  {
60  get
61  {
62  string rate;
63 
64  switch (config.PacketRate)
65  {
66  case 60:
67  rate = "second";
68  break;
69  case 1:
70  rate = "minute";
71  break;
72  default:
73  rate = config.PacketRate > 60
74  ? "second/" + config.PacketRate/60
75  : "minute/" + config.PacketRate;
76  break;
77  }
78 
79  return $"Packets per {rate}";
80  }
81  }
82 
83  protected override void AddPlots()
84  {
85  if (config.Received.HasValue)
86  {
87  var receivedPlot = SetupPlot("Packets received" + FText(config.Received.Value), Color.Green, time,
88  received);
89  Surface.Add(receivedPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
90  }
91 
92  if (config.ReceivedAvg.HasValue)
93  {
94  var receivedAvgPlot = SetupPlot(
95  "Packets received accumulated" + FText(config.ReceivedAvg.Value),
96  Color.Orange,
97  time,
98  receivedAvg);
99 
100  Surface.Add(receivedAvgPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
101 
102  var receivedAvgTotPlot = SetupPlot(
103  "Packets received since reset" + FText(config.ReceivedAvg.Value),
104  Color.Purple,
105  time,
106  receivedAvgTot);
107 
108  Surface.Add(receivedAvgTotPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
109  }
110 
111  if (config.Dropped.HasValue)
112  {
113  var droppedPlot = SetupPlot("Packets dropped" + FText(config.Dropped.Value), Color.Red, time, dropped);
114  Surface.Add(droppedPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
115  }
116 
117  if (config.Ignored.HasValue)
118  {
119  var ignoredPlot = SetupPlot("Packets ignored" + FText(config.Ignored.Value), Color.Blue, time, ignored);
120  Surface.Add(ignoredPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
121  }
122 
123  if (config.Sent.HasValue)
124  {
125  var sentPlot = SetupPlot("Packets sent" + FText(config.Sent.Value), Color.Black, time, sent);
126  Surface.Add(sentPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
127  }
128 
129  if (config.NotSent.HasValue)
130  {
131  var notSentPlot = SetupPlot("Packets not sent" + FText(config.NotSent.Value), Color.DarkRed, time,
132  notSent);
133  Surface.Add(notSentPlot, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Left);
134  }
135  }
136 
137  protected override void LoadData()
138  {
140  dataMapper.FilterHost = host;
141  dataMapper.FilterTime = DateTime.UtcNow.Subtract(GraphTimeSpan);
142 
143  var startTime = DateTime.MinValue;
144 
145  var firstTime = DateTime.MinValue;
146  long firstReceived = 0;
147  long firstIgnored = 0;
148  long firstDropped = 0;
149  long firstSent = 0;
150  long firstNotSent = 0;
151 
152  var lastTime = DateTime.MinValue;
153  long lastReceived = 0;
154  long lastIgnored = 0;
155  long lastDropped = 0;
156  long lastSent = 0;
157  long lastNotSent = 0;
158 
159  bool firstRun = true;
160  int disFactor = config.PacketRate;
161  int interval = config.PlotInterval*config.Timespan;
162 
163  foreach (var reading in dataMapper)
164  {
165  bool readNext = false;
166  var readingTime = config.GraphTime == DateTimeKind.Local
167  ? reading.RoundedLocalTime
168  : reading.RoundedUtcTime;
169 
170  if (!firstRun)
171  {
172  double minutes = readingTime.Subtract(lastTime).TotalMinutes;
173  double totalMinutes = readingTime.Subtract(firstTime).TotalMinutes;
174  double minutesSinceReset = readingTime.Subtract(startTime).TotalMinutes;
175 
176  if (minutes >= interval)
177  {
178  time.Add(readingTime);
179 
180  received.Add((reading.ReceivedPackets - lastReceived)*config.Received/minutes/disFactor ?? 0.0);
181  ignored.Add((reading.IgnoredPackets - lastIgnored)*config.Ignored/minutes/disFactor ?? 0.0);
182  dropped.Add((reading.DroppedPackets - lastDropped)*config.Dropped/minutes/disFactor ?? 0.0);
183  sent.Add((reading.PacketsSent - lastSent)*config.Sent/minutes/disFactor ?? 0.0);
184  notSent.Add((reading.PacketsNotSent - lastNotSent)*config.NotSent/minutes/disFactor ?? 0.0);
185  receivedAvg.Add((reading.ReceivedPackets - firstReceived)*config.ReceivedAvg/totalMinutes/
186  disFactor ?? 0.0);
187 
188  // TODO
189  if (config.ReceivedAvg.HasValue)
190  receivedAvgTot.Add(reading.ReceivedPackets*config.ReceivedAvg.Value/minutesSinceReset/
191  disFactor);
192  else
193  receivedAvgTot.Add(0.0);
194 
195  if (config.IgnoredAvg.HasValue)
196  ignoredAvg.Add((reading.IgnoredPackets - firstIgnored)*config.IgnoredAvg.Value/totalMinutes/
197  disFactor);
198  else
199  ignoredAvg.Add(0.0);
200 
201  if (config.DroppedAvg.HasValue)
202  droppedAvg.Add((reading.DroppedPackets - firstDropped)*config.DroppedAvg.Value/totalMinutes/
203  disFactor);
204  else
205  droppedAvg.Add(0.0);
206 
207  if (config.SentAvg.HasValue)
208  sentAvg.Add((reading.PacketsSent - firstSent)*config.SentAvg.Value/totalMinutes/disFactor);
209  else
210  sentAvg.Add(0.0);
211 
212  if (config.NotSentAvg.HasValue)
213  notSentAvg.Add((reading.PacketsNotSent - firstNotSent)*config.NotSentAvg.Value/totalMinutes/
214  disFactor);
215  else
216  notSentAvg.Add(0.0);
217 
218  readNext = true;
219  }
220  }
221  else
222  {
223  int hours = reading.TimeSinceReset/(60*60);
224  int mins = (reading.TimeSinceReset - hours*60*60)/60;
225  int seconds = reading.TimeSinceReset - hours*60*60 - mins*60;
226  var span = new TimeSpan(hours, mins, seconds);
227  startTime = readingTime.Subtract(span);
228 
229  firstTime = readingTime;
230  firstReceived = reading.ReceivedPackets;
231  firstIgnored = reading.IgnoredPackets;
232  firstDropped = reading.DroppedPackets;
233  firstSent = reading.PacketsSent;
234  firstNotSent = reading.PacketsNotSent;
235  }
236 
237  if (firstRun || readNext)
238  {
239  lastTime = readingTime;
240  lastReceived = reading.ReceivedPackets;
241  lastIgnored = reading.IgnoredPackets;
242  lastDropped = reading.DroppedPackets;
243  lastSent = reading.PacketsSent;
244  lastNotSent = reading.PacketsNotSent;
245  }
246 
247  firstRun = false;
248  }
249  }
250 
251  protected override void PreRender()
252  {
253  base.PreRender();
254 
255  Surface.YAxis1.NumberFormat = "{0:####0}";
256  }
257 
258  private static string FText(double value)
259  {
260  return Math.Abs(value - 1.0) > 0.0
261  ? " x " + value.ToString("0", CultureInfo.InvariantCulture)
262  : string.Empty;
263  }
264  }
265 }
DateTime FilterTime
Gets or sets the time to use when extracting data. Only readings with a timestamp later than FilterTi...
readonly ITrafficGraphConfiguration config
Definition: TrafficGraph.cs:43
Singleton facade class used to access memory persistent data.
Definition: DataFace.cs:30
TrafficGraph(ITrafficGraphConfiguration configuration, Host host)
Definition: TrafficGraph.cs:36
static DataFace Instance
Gets the Singleton instance.
Definition: DataFace.cs:51
static string FText(double value)
HostIoReadingDatabaseMapper HostIoReadings
Gets the host IO reading mapper.
Definition: DataFace.cs:81