Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
EventStatisticsCommand.cs
1using System;
3using System.Reflection;
4using System.Text;
5using System.Threading.Tasks;
10using Waher.Things;
13
15{
20 {
26 : base(ReportNode)
27 {
28 }
29
30 [Page(7, "Time", 150)]
31 [Header(8, "From:")]
32 [ToolTip(9, "Search for events from this point in time.")]
33 public DateTime From = DateTime.Today.AddDays(-1);
34
35 [Page(7, "Time", 150)]
36 [Header(10, "To:")]
37 [ToolTip(11, "Search for events to this point in time.")]
38 public DateTime To = DateTime.Today.AddDays(1);
39
40 public override Task<string> GetNameAsync(Language Language)
41 {
42 return Language.GetStringAsync(typeof(SearchEventsCommand), 59, "Statistics...");
43 }
44
49 public override ICommand Copy()
50 {
52 {
53 From = this.From,
54 To = this.To
55 };
56 }
57
64 {
65 this.Execute(Query, Language);
66 return Task.CompletedTask;
67 }
68
69 private async void Execute(Query Query, Language Language)
70 {
71 try
72 {
73 await Query.Start();
74 await Query.SetTitle(await Language.GetStringAsync(typeof(SearchEventsCommand), 47, "Events"));
75
76 if (this.To < this.From)
77 {
78 DateTime Temp = this.To;
79 this.To = this.From;
80 this.From = Temp;
81 }
82
83 List<Filter> Filters = new List<Filter>();
84 if (this.From > DateTime.MinValue)
85 Filters.Add(new FilterFieldGreaterOrEqualTo("Timestamp", this.From));
86
87 if (this.To < DateTime.MaxValue)
88 Filters.Add(new FilterFieldLesserOrEqualTo("Timestamp", this.To));
89
90 await Query.SetStatus(await Language.GetStringAsync(typeof(SearchEventsCommand), 48, "Searching database..."));
91
92 IEnumerable<EventStatistic> Records = Filters.Count switch
93 {
94 0 => await Database.Find<EventStatistic>("Timestamp"),
95 1 => await Database.Find<EventStatistic>(Filters[0], "Timestamp"),
96 _ => await Database.Find<EventStatistic>(new FilterAnd(Filters.ToArray()), "Timestamp"),
97 };
98
99 await this.ReportRecords(Records, Query, Language, "PerType",
100 await Language.GetStringAsync(typeof(SearchEventsCommand), 61, "Events per Type"));
101
102 await this.ReportRecords(Records, Query, Language, "PerLevel",
103 await Language.GetStringAsync(typeof(SearchEventsCommand), 62, "Events per Level"));
104
105 await this.ReportRecords(Records, Query, Language, "PerEventId",
106 await Language.GetStringAsync(typeof(SearchEventsCommand), 63, "Events per Event ID"));
107
108 await this.ReportRecords(Records, Query, Language, "PerActor",
109 await Language.GetStringAsync(typeof(SearchEventsCommand), 64, "Events per Actor"));
110
111 await this.ReportRecords(Records, Query, Language, "PerModule",
112 await Language.GetStringAsync(typeof(SearchEventsCommand), 65, "Events per Module"));
113
114 await this.ReportRecords(Records, Query, Language, "PerFacility",
115 await Language.GetStringAsync(typeof(SearchEventsCommand), 66, "Events per Facility"));
116
117 await this.ReportStackTraces(Records, Query, Language);
118 }
119 catch (Exception ex)
120 {
121 await Query.LogMessage(ex);
122 }
123 finally
124 {
125 await Query.Done();
126 }
127 }
128
129 private async Task ReportRecords(IEnumerable<EventStatistic> Records, Query Query, Language Language,
130 string Property, string SectionName)
131 {
132 SortedDictionary<string, int> Labels = new SortedDictionary<string, int>();
133 PropertyInfo PI = typeof(EventStatistic).GetProperty(Property);
134 int i = 0;
135
136 foreach (EventStatistic Rec in Records)
137 {
138 foreach (Statistic Stat in (Statistic[])PI.GetValue(Rec))
139 {
140 if (!Labels.ContainsKey(Stat.Name))
141 Labels[Stat.Name] = i++;
142 }
143 }
144
145 List<Column> Columns = new List<Column>()
146 {
147 new Column("Start", await Language.GetStringAsync(typeof(SearchEventsCommand), 60, "Start"),
148 null, null, null, null, ColumnAlignment.Left, null),
149 new Column("Timestamp", await Language.GetStringAsync(typeof(SearchEventsCommand), 50, "Timestamp"),
150 null, null, null, null, ColumnAlignment.Left, null)
151 };
152
153 SortedDictionary<string, int> IndexByName = new SortedDictionary<string, int>();
154 i = 2;
155
156 foreach (KeyValuePair<string, int> Header in Labels)
157 {
158 Columns.Add(new Column("C" + Header.Value.ToString(), Header.Key, null, null, null, null, ColumnAlignment.Right, null));
159 IndexByName[Header.Key] = i++;
160 }
161
162 int c = Columns.Count;
163
164 await Query.BeginSection(SectionName);
165 await Query.NewTable(Property, SectionName, Columns.ToArray());
166
167 foreach (EventStatistic Rec in Records)
168 {
169 object[] Record = new object[c];
170 Record[0] = Rec.Start;
171 Record[1] = Rec.Timestamp;
172
173 foreach (Statistic Stat in (Statistic[])PI.GetValue(Rec))
174 {
175 if (IndexByName.TryGetValue(Stat.Name, out i))
176 Record[i] = Stat.Count;
177 }
178
179 await Query.NewRecords(Property, new Record(Record));
180 }
181
182 await Query.TableDone(Property);
183 await Query.EndSection();
184 }
185
186 private async Task ReportStackTraces(IEnumerable<EventStatistic> Records, Query Query, Language Language)
187 {
188 SortedDictionary<string, int> Labels = new SortedDictionary<string, int>();
189 int i = 0;
190
191 foreach (EventStatistic Rec in Records)
192 {
193 foreach (Statistic Stat in Rec.PerStackTrace)
194 {
195 if (!Labels.ContainsKey(Stat.Name))
196 Labels[Stat.Name] = i++;
197 }
198 }
199
200 List<Column> Columns = new List<Column>()
201 {
202 new Column("Start", await Language.GetStringAsync(typeof(SearchEventsCommand), 60, "Start"),
203 null, null, null, null, ColumnAlignment.Left, null),
204 new Column("Timestamp", await Language.GetStringAsync(typeof(SearchEventsCommand), 50, "Timestamp"),
205 null, null, null, null, ColumnAlignment.Left, null),
206 new Column("Count", await Language.GetStringAsync(typeof(SearchEventsCommand), 68, "Count"),
207 null, null, null, null, ColumnAlignment.Right, null)
208 };
209
210 await Query.BeginSection(await Language.GetStringAsync(typeof(SearchEventsCommand), 67, "Events per Stack Trace"));
211
212 string StackTraceLabel = await Language.GetStringAsync(typeof(SearchEventsCommand), 69, "Stack Trace");
213
214 i = 0;
215
216 foreach (string StackTrace in Labels.Keys)
217 {
218 StringBuilder Markdown = new StringBuilder();
219
220 Markdown.AppendLine("```");
221 Markdown.AppendLine(StackTrace);
222 Markdown.AppendLine("```");
223
224 await Query.NewObject(new MarkdownContent(Markdown.ToString()));
225
226 string TableId = "T" + i++.ToString();
227
228 await Query.NewTable(TableId, StackTraceLabel + " " + i.ToString(), Columns.ToArray());
229
230 foreach (EventStatistic Rec in Records)
231 {
232 object[] Record = new object[]
233 {
234 Rec.Start,
235 Rec.Timestamp,
236 0
237 };
238
239 foreach (Statistic Stat in Rec.PerStackTrace)
240 {
241 if (Stat.Name == StackTrace)
242 {
243 Record[2] = Stat.Count;
244 break;
245 }
246 }
247
248 await Query.NewRecords(TableId, new Record(Record));
249 }
250
251 await Query.TableDone(TableId);
252 }
253
254 await Query.EndSection();
255 }
256
257 }
258}
Class that can be used to encapsulate Markdown to be returned from a Web Service, bypassing any encod...
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:238
This filter selects objects that conform to all child-filters provided.
Definition: FilterAnd.cs:10
This filter selects objects that have a named field greater or equal to a given value.
This filter selects objects that have a named field lesser or equal to a given value.
ReportNode Report
Report node.
Contains information about a language.
Definition: Language.cs:17
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
Definition: Language.cs:209
Query command that returns statistics of events logged to the event log.
EventStatisticsCommand(EventStatisticsNode ReportNode)
Query command that returns statistics of events logged to the event log.
override Task StartQueryExecutionAsync(Query Query, Language Language)
Starts the execution of a query.
override Task< string > GetNameAsync(Language Language)
Gets the displayable name of the command.
Abstract base class for commands executing a server administrator report.
Defines a column in a table.
Definition: Column.cs:30
Class handling the reception of data from a query.
Definition: Query.cs:12
Task TableDone(string TableId)
Reports a table as being complete.
Definition: Query.cs:327
Task EndSection()
Ends a section. Each call to BeginSection(string) must be followed by a call to EndSection().
Definition: Query.cs:504
Task NewObject(object Object)
Reports a new object.
Definition: Query.cs:354
Task Start()
Starts query execution.
Definition: Query.cs:213
Task NewRecords(string TableId, params Record[] Records)
Reports a new set of records in a table.
Definition: Query.cs:300
Task BeginSection(string Header)
Begins a new section. Sections can be nested. Each call to BeginSection(string) must be followed by a...
Definition: Query.cs:483
Task NewTable(string TableId, string TableName, params Column[] Columns)
Defines a new table in the query output.
Definition: Query.cs:272
Task LogMessage(Exception Exception)
Logs an Exception as a query message.
Definition: Query.cs:381
async Task Done()
Query execution completed.
Definition: Query.cs:241
Task SetStatus(string Status)
Sets the current status of the query execution.
Definition: Query.cs:457
Task SetTitle(string Title)
Sets the title of the report.
Definition: Query.cs:430
Defines a record in a table.
Definition: Record.cs:9
Interface for commands.
Definition: ICommand.cs:32
Definition: ImplTypes.g.cs:58
class Header(ISimulationNode Parent, Model Model)
Represents an identity property.
Definition: Header.cs:18
ColumnAlignment
Column alignment.
Definition: Column.cs:9