aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Monitoring/ChecksManager.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Monitoring/ChecksManager.cs262
1 files changed, 262 insertions, 0 deletions
diff --git a/OpenSim/Framework/Monitoring/ChecksManager.cs b/OpenSim/Framework/Monitoring/ChecksManager.cs
new file mode 100644
index 0000000..e4a7f8c
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/ChecksManager.cs
@@ -0,0 +1,262 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using log4net;
34
35namespace OpenSim.Framework.Monitoring
36{
37 /// <summary>
38 /// Static class used to register/deregister checks on runtime conditions.
39 /// </summary>
40 public static class ChecksManager
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 // Subcommand used to list other stats.
45 public const string ListSubCommand = "list";
46
47 // All subcommands
48 public static HashSet<string> SubCommands = new HashSet<string> { ListSubCommand };
49
50 /// <summary>
51 /// Checks categorized by category/container/shortname
52 /// </summary>
53 /// <remarks>
54 /// Do not add or remove directly from this dictionary.
55 /// </remarks>
56 public static SortedDictionary<string, SortedDictionary<string, SortedDictionary<string, Check>>> RegisteredChecks
57 = new SortedDictionary<string, SortedDictionary<string, SortedDictionary<string, Check>>>();
58
59 public static void RegisterConsoleCommands(ICommandConsole console)
60 {
61 console.Commands.AddCommand(
62 "General",
63 false,
64 "show checks",
65 "show checks",
66 "Show checks configured for this server",
67 "If no argument is specified then info on all checks will be shown.\n"
68 + "'list' argument will show check categories.\n"
69 + "THIS FACILITY IS EXPERIMENTAL",
70 HandleShowchecksCommand);
71 }
72
73 public static void HandleShowchecksCommand(string module, string[] cmd)
74 {
75 ICommandConsole con = MainConsole.Instance;
76
77 if (cmd.Length > 2)
78 {
79 foreach (string name in cmd.Skip(2))
80 {
81 string[] components = name.Split('.');
82
83 string categoryName = components[0];
84// string containerName = components.Length > 1 ? components[1] : null;
85
86 if (categoryName == ListSubCommand)
87 {
88 con.Output("check categories available are:");
89
90 foreach (string category in RegisteredChecks.Keys)
91 con.OutputFormat(" {0}", category);
92 }
93// else
94// {
95// SortedDictionary<string, SortedDictionary<string, Check>> category;
96// if (!Registeredchecks.TryGetValue(categoryName, out category))
97// {
98// con.OutputFormat("No such category as {0}", categoryName);
99// }
100// else
101// {
102// if (String.IsNullOrEmpty(containerName))
103// {
104// OutputConfiguredToConsole(con, category);
105// }
106// else
107// {
108// SortedDictionary<string, Check> container;
109// if (category.TryGetValue(containerName, out container))
110// {
111// OutputContainerChecksToConsole(con, container);
112// }
113// else
114// {
115// con.OutputFormat("No such container {0} in category {1}", containerName, categoryName);
116// }
117// }
118// }
119// }
120 }
121 }
122 else
123 {
124 OutputAllChecksToConsole(con);
125 }
126 }
127
128 /// <summary>
129 /// Registers a statistic.
130 /// </summary>
131 /// <param name='stat'></param>
132 /// <returns></returns>
133 public static bool RegisterCheck(Check check)
134 {
135 SortedDictionary<string, SortedDictionary<string, Check>> category = null, newCategory;
136 SortedDictionary<string, Check> container = null, newContainer;
137
138 lock (RegisteredChecks)
139 {
140 // Check name is not unique across category/container/shortname key.
141 // XXX: For now just return false. This is to avoid problems in regression tests where all tests
142 // in a class are run in the same instance of the VM.
143 if (TryGetCheckParents(check, out category, out container))
144 return false;
145
146 // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
147 // This means that we don't need to lock or copy them on iteration, which will be a much more
148 // common operation after startup.
149 if (container != null)
150 newContainer = new SortedDictionary<string, Check>(container);
151 else
152 newContainer = new SortedDictionary<string, Check>();
153
154 if (category != null)
155 newCategory = new SortedDictionary<string, SortedDictionary<string, Check>>(category);
156 else
157 newCategory = new SortedDictionary<string, SortedDictionary<string, Check>>();
158
159 newContainer[check.ShortName] = check;
160 newCategory[check.Container] = newContainer;
161 RegisteredChecks[check.Category] = newCategory;
162 }
163
164 return true;
165 }
166
167 /// <summary>
168 /// Deregister an check
169 /// </summary>>
170 /// <param name='stat'></param>
171 /// <returns></returns>
172 public static bool DeregisterCheck(Check check)
173 {
174 SortedDictionary<string, SortedDictionary<string, Check>> category = null, newCategory;
175 SortedDictionary<string, Check> container = null, newContainer;
176
177 lock (RegisteredChecks)
178 {
179 if (!TryGetCheckParents(check, out category, out container))
180 return false;
181
182 newContainer = new SortedDictionary<string, Check>(container);
183 newContainer.Remove(check.ShortName);
184
185 newCategory = new SortedDictionary<string, SortedDictionary<string, Check>>(category);
186 newCategory.Remove(check.Container);
187
188 newCategory[check.Container] = newContainer;
189 RegisteredChecks[check.Category] = newCategory;
190
191 return true;
192 }
193 }
194
195 public static bool TryGetCheckParents(
196 Check check,
197 out SortedDictionary<string, SortedDictionary<string, Check>> category,
198 out SortedDictionary<string, Check> container)
199 {
200 category = null;
201 container = null;
202
203 lock (RegisteredChecks)
204 {
205 if (RegisteredChecks.TryGetValue(check.Category, out category))
206 {
207 if (category.TryGetValue(check.Container, out container))
208 {
209 if (container.ContainsKey(check.ShortName))
210 return true;
211 }
212 }
213 }
214
215 return false;
216 }
217
218 public static void CheckChecks()
219 {
220 lock (RegisteredChecks)
221 {
222 foreach (SortedDictionary<string, SortedDictionary<string, Check>> category in RegisteredChecks.Values)
223 {
224 foreach (SortedDictionary<string, Check> container in category.Values)
225 {
226 foreach (Check check in container.Values)
227 {
228 if (!check.CheckIt())
229 m_log.WarnFormat(
230 "[CHECKS MANAGER]: Check {0}.{1}.{2} failed with message {3}", check.Category, check.Container, check.ShortName, check.LastFailureMessage);
231 }
232 }
233 }
234 }
235 }
236
237 private static void OutputAllChecksToConsole(ICommandConsole con)
238 {
239 foreach (var category in RegisteredChecks.Values)
240 {
241 OutputCategoryChecksToConsole(con, category);
242 }
243 }
244
245 private static void OutputCategoryChecksToConsole(
246 ICommandConsole con, SortedDictionary<string, SortedDictionary<string, Check>> category)
247 {
248 foreach (var container in category.Values)
249 {
250 OutputContainerChecksToConsole(con, container);
251 }
252 }
253
254 private static void OutputContainerChecksToConsole(ICommandConsole con, SortedDictionary<string, Check> container)
255 {
256 foreach (Check check in container.Values)
257 {
258 con.Output(check.ToConsoleString());
259 }
260 }
261 }
262} \ No newline at end of file