2
* Copyright © 2013 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Alan Griffiths <alan@octopull.co.uk>
19
#include "message_processor_report.h"
20
#include "mir/logging/logger.h"
22
#include <boost/exception/diagnostic_information.hpp>
25
namespace ml = mir::logging;
26
namespace mrl = mir::report::logging;
30
char const* const component = "frontend::MessageProcessor";
34
mrl::MessageProcessorReport::MessageProcessorReport(
35
std::shared_ptr<ml::Logger> const& log,
36
std::shared_ptr<time::Clock> const& clock) :
42
mrl::MessageProcessorReport::~MessageProcessorReport() noexcept(true)
44
if (!mediators.empty())
46
std::ostringstream out;
49
out << "Calls outstanding on exit:\n";
51
std::lock_guard<std::mutex> lock(mutex);
53
for (auto const& med : mediators)
55
for (auto const & invocation: med.second.current_invocations)
57
out << "mediator=" << med.first << ": "
58
<< invocation.second.method << "()";
60
if (!invocation.second.exception.empty())
61
out << " ERROR=" << invocation.second.exception;
68
log->log(ml::Logger::informational, out.str(), component);
73
void mrl::MessageProcessorReport::received_invocation(void const* mediator, int id, std::string const& method)
75
std::ostringstream out;
76
out << "mediator=" << mediator << ", method=" << method << "()";
77
log->log(ml::Logger::debug, out.str(), component);
79
std::lock_guard<std::mutex> lock(mutex);
80
auto& invocations = mediators[mediator].current_invocations;
81
auto& invocation = invocations[id];
83
invocation.start = clock->sample();
84
invocation.method = method;
87
void mrl::MessageProcessorReport::completed_invocation(void const* mediator, int id, bool result)
89
auto const end = clock->sample();
90
std::ostringstream out;
93
std::lock_guard<std::mutex> lock(mutex);
95
auto const pm = mediators.find(mediator);
96
if (pm != mediators.end())
98
auto& invocations = pm->second.current_invocations;
100
auto const pi = invocations.find(id);
101
if (pi != invocations.end())
103
out << "mediator=" << mediator << ": "
104
<< pi->second.method << "(), elapsed="
105
<< std::chrono::duration_cast<std::chrono::microseconds>(end - pi->second.start).count()
108
if (!pi->second.exception.empty())
109
out << " ERROR=" << pi->second.exception;
112
out << " (disconnecting)";
115
invocations.erase(pi);
117
if (invocations.empty())
118
mediators.erase(mediator);
122
log->log(ml::Logger::informational, out.str(), component);
125
void mrl::MessageProcessorReport::unknown_method(void const* mediator, int id, std::string const& method)
127
std::ostringstream out;
128
out << "mediator=" << mediator << ", id=" << id << ", UNKNOWN method=\"" << method << "\"";
129
log->log(ml::Logger::warning, out.str(), component);
131
std::lock_guard<std::mutex> lock(mutex);
132
auto const pm = mediators.find(mediator);
133
if (pm != mediators.end())
134
mediators.erase(mediator);
137
void mrl::MessageProcessorReport::exception_handled(void const* mediator, int id, std::exception const& error)
139
std::lock_guard<std::mutex> lock(mutex);
141
auto const pm = mediators.find(mediator);
142
if (pm != mediators.end())
144
auto& invocations = pm->second.current_invocations;
146
auto const pi = invocations.find(id);
147
if (pi != invocations.end())
149
pi->second.exception = boost::diagnostic_information(error);
154
void mrl::MessageProcessorReport::exception_handled(void const* mediator, std::exception const& error)
156
std::ostringstream out;
157
out << "mediator=" << mediator << ", ERROR: " << boost::diagnostic_information(error);
158
log->log(ml::Logger::informational, out.str(), component);
160
std::lock_guard<std::mutex> lock(mutex);
161
auto const pm = mediators.find(mediator);
162
if (pm != mediators.end())
163
mediators.erase(mediator);
166
void mrl::MessageProcessorReport::sent_event(void const* mediator, MirSurfaceEvent const& event)
168
std::ostringstream out;
169
out << "mediator=" << mediator << ", sent event, surface id=" << event.id;
170
log->log(ml::Logger::debug, out.str(), component);