1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #include <anna/core/tracing/TraceMethod.hpp>
38 #include <anna/core/tracing/Logger.hpp>
40 #include <anna/xml/Node.hpp>
41 #include <anna/xml/Attribute.hpp>
43 #include <anna/timex/Engine.hpp>
45 #include <anna/core/oam/CounterManager.hpp>
46 #include <anna/core/oam/CounterRecorder.hpp>
47 #include <anna/core/oam/CounterSummarizer.hpp>
53 oam::CounterManager::CounterManager() :
55 a_timeController(NULL),
56 a_counterRecorder(NULL),
57 a_counterSummarizer(NULL),
59 anna_memset(a_scopes, 0, sizeof(a_scopes));
62 oam::CounterManager::~CounterManager() {
63 for(register int i = 0; i < MaxScope; i ++)
67 oam::CounterScope& oam::CounterManager::create(const int scope, const char* name, bool reuse)
68 throw(RuntimeException) {
69 if(scope >= MaxScope) {
70 string msg(CounterScope(*this, scope, name).asString());
71 msg += " | Out of range";
72 throw RuntimeException(msg, ANNA_FILE_LOCATION);
75 bool exists = (a_scopes [scope] != NULL);
78 string msg(CounterScope(*this, scope, name).asString());
79 msg += " | Id was already registered as ";
80 msg += a_scopes [scope]->asString();
83 throw RuntimeException(msg, ANNA_FILE_LOCATION);
85 LOGWARNING(Logger::warning(msg, ANNA_FILE_LOCATION));
87 a_scopes [scope] = new CounterScope(*this, scope, name);
89 return *(a_scopes [scope]);
92 oam::CounterScope& oam::CounterManager::find(const int scope)
93 throw(RuntimeException) {
94 if(scope >= MaxScope) {
95 string msg(CounterScope(*this, scope, "(none)").asString());
96 msg += " | Out of range";
97 throw RuntimeException(msg, ANNA_FILE_LOCATION);
100 if(a_scopes [scope] == NULL) {
101 string msg(CounterScope(*this, scope, "(none)").asString());
102 msg += " | Was not created";
103 throw RuntimeException(msg, ANNA_FILE_LOCATION);
106 return *(a_scopes [scope]);
109 const oam::CounterScope& oam::CounterManager::find(const int scope) const
110 throw(RuntimeException) {
111 const CounterScope& result = const_cast <oam::CounterManager*>(this)->find(scope);
116 // Se invoca desde oam::CounterScope
117 void oam::CounterManager::activateTimer()
118 throw(RuntimeException) {
119 static bool warning = false;
121 if(a_timeController == NULL) {
122 if(warning == false) {
126 "anna::oam::CounterManager has no time manager associated. Counters won't be dumped",
136 if(a_counterRecorder == NULL) {
140 "anna::oam::CounterManager has no counter recorder associated. Ignore record operation.",
147 if(a_timer.isActive() == false && a_recording == false) {
149 a_timeController->activate(a_timer);
150 } catch(RuntimeException& ex) {
156 // Al invocar a este método el timex::Engine tiene activa una SSCC
157 void oam::CounterManager::record()
158 throw(RuntimeException) {
159 LOGMETHOD(TraceMethod traceMethod("anna::oam::CounterManager", "record", ANNA_FILE_LOCATION));
161 if(a_counterRecorder == NULL)
162 throw RuntimeException("anna::oam::CounterManager has no counter recorder associated", ANNA_FILE_LOCATION);
165 string msg("Recording counters | ");
166 msg += a_counterRecorder->asString();
167 Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
169 RecordingGuard guard(this);
171 if(a_counterSummarizer != NULL)
172 a_counterSummarizer->apply();
174 a_counterRecorder->open();
175 Counter* counter = NULL;
176 CounterScope* scope = NULL;
179 for(register int iscope = 0; iscope < MaxScope; iscope ++) {
180 if((scope = a_scopes [iscope]) == NULL) continue;
182 CounterScope& counterScope(*a_scopes [iscope]);
183 // Al invocar a este método el timex::Engine ya está protegido => no hace falta volver a hacerlo
184 CounterScope::Safe locker(NULL, counterScope, "oam::CounterManager::record");
186 for(register int icounter = 0; icounter < CounterScope::MaxCounter; icounter ++) {
187 Counter* counter = counterScope.a_counters [icounter];
192 if(counter->getValue() == 0)
195 a_counterRecorder->apply(*counter);
200 a_counterRecorder->close();
201 } catch(RuntimeException&) {
202 a_counterRecorder->close();
207 xml::Node* oam::CounterManager::asXML(xml::Node* parent) const
208 throw(RuntimeException) {
209 xml::Node* result = parent->createChild("oam.CounterManager");
211 for(int ii = 0; ii < MaxScope; ii ++) {
212 if(a_scopes [ii] != NULL) {
213 // Observar que el Scope no conoce SU id.
214 a_scopes [ii]->asXML(result)->createAttribute("Id", ii);
221 oam::CounterManager::RecordingGuard::RecordingGuard(CounterManager* counterManager) :
222 a_counterManager(counterManager) {
223 counterManager->a_recording = true;
226 oam::CounterManager::RecordingGuard::~RecordingGuard() {
227 a_counterManager->a_recording = false;
231 void oam::CounterManager::count(const int scope, const int counter, const oam::Counter::type_t value)
233 CounterManager& ccmm = CounterManager::instantiate();
236 oam::CounterScope::Safe counterScope(ccmm.a_timeController, ccmm.find(scope), "oam::CounterManager::count");
237 counterScope.increment(counter, value);
238 } catch(Exception& ex) {