Mir

Merge lp:~dandrader/mir/ainput-log-filtering into lp:~mir-team/mir/trunk

Proposed by Daniel d'Andrada
Status: Superseded
Proposed branch: lp:~dandrader/mir/ainput-log-filtering
Merge into: lp:~mir-team/mir/trunk
Diff against target: 282 lines (+176/-27)
2 files modified
3rd_party/android-input/android/frameworks/base/services/input/MirLog.cpp (+157/-5)
tests/unit-tests/logging/test_legacy_input_report.cpp (+19/-22)
To merge this branch: bzr merge lp:~dandrader/mir/ainput-log-filtering
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Mir development team Pending
Review via email: mp+187316@code.launchpad.net

This proposal has been superseded by a proposal from 2013-09-25.

Commit message

Bring back android-input logging functionality

- prefix log message with the tag name from where the log function was called.
- filter log messages by tag name and priority with the ANDROID_LOG_TAGS
  environment var

Description of the change

Bring back android-input logging functionality

- prefix log message with the tag name from where the log function was called.
- filter log messages by tag name and priority with the ANDROID_LOG_TAGS
  environment var

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/frameworks/base/services/input/MirLog.cpp'
2--- 3rd_party/android-input/android/frameworks/base/services/input/MirLog.cpp 2013-05-04 00:50:30 +0000
3+++ 3rd_party/android-input/android/frameworks/base/services/input/MirLog.cpp 2013-09-24 19:24:51 +0000
4@@ -14,13 +14,143 @@
5 * along with this program. If not, see <http://www.gnu.org/licenses/>.
6 *
7 * Authored by: Alan Griffiths <alan@octopull.co.uk>
8- */
9-
10-#include <std/Log.h>
11+ * Daniel d'Andrada <daniel.dandrada@canonical.com>
12+ */
13+
14+// License of the original configureInitialState() function:
15+/*
16+ * Copyright (C) 2008 The Android Open Source Project
17+ *
18+ * Licensed under the Apache License, Version 2.0 (the "License");
19+ * you may not use this file except in compliance with the License.
20+ * You may obtain a copy of the License at
21+ *
22+ * http://www.apache.org/licenses/LICENSE-2.0
23+ *
24+ * Unless required by applicable law or agreed to in writing, software
25+ * distributed under the License is distributed on an "AS IS" BASIS,
26+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27+ * See the License for the specific language governing permissions and
28+ * limitations under the License.
29+ */
30+
31+#include <android/log.h>
32 #include <std/MirLog.h>
33+#include <cctype>
34 #include <cstdarg>
35 #include <cstdio>
36-
37+#include <cstdlib>
38+#include <cstring>
39+
40+#define kMaxTagLen 16 /* from the long-dead utils/Log.cpp */
41+#define kTagSetSize 16 /* arbitrary */
42+
43+namespace
44+{
45+ struct LogState {
46+ /* global minimum priority */
47+ int globalMinPriority;
48+
49+ /* tags and priorities */
50+ struct {
51+ char tag[kMaxTagLen];
52+ int minPriority;
53+ } tagSet[kTagSetSize];
54+ } gLogState = { .globalMinPriority = ANDROID_LOG_UNKNOWN };
55+}
56+
57+/*
58+ * Configure logging based on ANDROID_LOG_TAGS environment variable. We
59+ * need to parse a string that looks like
60+ *
61+ * *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
62+ *
63+ * The tag (or '*' for the global level) comes first, followed by a colon
64+ * and a letter indicating the minimum priority level we're expected to log.
65+ * This can be used to reveal or conceal logs with specific tags.
66+ *
67+ * We also want to check ANDROID_PRINTF_LOG to determine how the output
68+ * will look.
69+ */
70+static void configureInitialState(struct LogState* logState)
71+{
72+ /* global min priority defaults to "info" level */
73+ logState->globalMinPriority = ANDROID_LOG_INFO;
74+
75+ int entry = 0;
76+
77+ /*
78+ * This is based on the the long-dead utils/Log.cpp code.
79+ */
80+ const char* tags = getenv("ANDROID_LOG_TAGS");
81+ if (tags != NULL) {
82+ while (*tags != '\0') {
83+ char tagName[kMaxTagLen];
84+ int i, minPrio;
85+
86+ while (isspace(*tags))
87+ tags++;
88+
89+ i = 0;
90+ while (*tags != '\0' && !isspace(*tags) && *tags != ':' &&
91+ i < kMaxTagLen)
92+ {
93+ tagName[i++] = *tags++;
94+ }
95+ if (i == kMaxTagLen) {
96+ break;
97+ }
98+ tagName[i] = '\0';
99+
100+ /* default priority, if there's no ":" part; also zero out '*' */
101+ minPrio = ANDROID_LOG_VERBOSE;
102+ if (tagName[0] == '*' && tagName[1] == '\0') {
103+ minPrio = ANDROID_LOG_DEBUG;
104+ tagName[0] = '\0';
105+ }
106+
107+ if (*tags == ':') {
108+ tags++;
109+ if (*tags >= '0' && *tags <= '9') {
110+ if (*tags >= ('0' + ANDROID_LOG_SILENT))
111+ minPrio = ANDROID_LOG_VERBOSE;
112+ else
113+ minPrio = *tags - '\0';
114+ } else {
115+ switch (*tags) {
116+ case 'v': minPrio = ANDROID_LOG_VERBOSE; break;
117+ case 'd': minPrio = ANDROID_LOG_DEBUG; break;
118+ case 'i': minPrio = ANDROID_LOG_INFO; break;
119+ case 'w': minPrio = ANDROID_LOG_WARN; break;
120+ case 'e': minPrio = ANDROID_LOG_ERROR; break;
121+ case 'f': minPrio = ANDROID_LOG_FATAL; break;
122+ case 's': minPrio = ANDROID_LOG_SILENT; break;
123+ default: minPrio = ANDROID_LOG_DEFAULT; break;
124+ }
125+ }
126+
127+ tags++;
128+ if (*tags != '\0' && !isspace(*tags)) {
129+ break;
130+ }
131+ }
132+
133+ if (tagName[0] == 0) {
134+ logState->globalMinPriority = minPrio;
135+ } else {
136+ logState->tagSet[entry].minPriority = minPrio;
137+ strcpy(logState->tagSet[entry].tag, tagName);
138+ entry++;
139+ }
140+ }
141+ }
142+
143+ if (entry < kTagSetSize) {
144+ // Mark the end of this array
145+ logState->tagSet[entry].minPriority = ANDROID_LOG_UNKNOWN;
146+ logState->tagSet[entry].tag[0] = '\0';
147+ }
148+}
149
150 extern "C" int __android_log_print(int prio, const char *tag, const char *fmt, ...)
151 {
152@@ -30,7 +160,29 @@
153 int result = vsnprintf(buffer, sizeof buffer - 1, fmt, ap);
154 va_end(ap);
155
156- mir::write_to_log(prio, buffer);
157+ if (gLogState.globalMinPriority == ANDROID_LOG_UNKNOWN) {
158+ configureInitialState(&gLogState);
159+ }
160+
161+ /* see if this log tag is configured */
162+ int minPrio = gLogState.globalMinPriority;
163+ for (int i = 0; i < kTagSetSize; i++) {
164+ if (gLogState.tagSet[i].minPriority == ANDROID_LOG_UNKNOWN)
165+ break; /* reached end of configured values */
166+
167+ if (strcmp(gLogState.tagSet[i].tag, tag) == 0) {
168+ minPrio = gLogState.tagSet[i].minPriority;
169+ break;
170+ }
171+ }
172+
173+ if (prio >= minPrio) {
174+ char taggedBuffer[1024];
175+ sprintf(taggedBuffer, "[%s]%s", tag, buffer);
176+ mir::write_to_log(prio, taggedBuffer);
177+ } else {
178+ // filter out log message
179+ }
180
181 return result;
182 }
183
184=== modified file 'tests/unit-tests/logging/test_legacy_input_report.cpp'
185--- tests/unit-tests/logging/test_legacy_input_report.cpp 2013-05-28 17:55:26 +0000
186+++ tests/unit-tests/logging/test_legacy_input_report.cpp 2013-09-24 19:24:51 +0000
187@@ -29,6 +29,8 @@
188 namespace ml = mir::logging;
189 namespace mli = mir::logging::legacy_input_report;
190
191+using testing::_;
192+
193 namespace
194 {
195 class MockLogger : public ml::Logger
196@@ -49,69 +51,64 @@
197 };
198
199 char const* const component = "android-input";
200-char const* const LOG_TAG = 0;
201+char const* const LOG_TAG = "Foo";
202 }
203
204 TEST_F(InputReport, debug_message)
205 {
206- EXPECT_CALL(logger, log(
207- ml::Logger::debug,
208- testing::HasSubstr(__PRETTY_FUNCTION__),
209- component));
210+ // default minimum log priority is "informational". "debug" is lower than that.
211+ EXPECT_CALL(logger, log(_, _, _)).Times(0);
212
213- ALOG(LOG_DEBUG, NULL, "Test function is %s", __PRETTY_FUNCTION__);
214+ ALOG(LOG_DEBUG, NULL, "Test function is %s", __PRETTY_FUNCTION__);
215 }
216
217 TEST_F(InputReport, unknown_message)
218 {
219 char const* const unknown = "Unknown message";
220
221- EXPECT_CALL(logger, log(
222- ml::Logger::debug,
223- unknown,
224- component));
225+ // default minimum log priority is "informational". "unknown" is lower than that.
226+ // Actually, I don't think this is even a valid priority.
227+ EXPECT_CALL(logger, log(_, _, _)).Times(0);
228
229- ALOG(LOG_UNKNOWN, NULL, unknown);
230+ ALOG(LOG_UNKNOWN, NULL, unknown);
231 }
232
233 TEST_F(InputReport, verbose_message)
234 {
235 char const* const verbose = "A very long story. (OK, I lied.)";
236
237- EXPECT_CALL(logger, log(
238- ml::Logger::debug,
239- verbose,
240- component));
241+ // default minimum log priority is "informational". "verbose" is lower than that.
242+ EXPECT_CALL(logger, log(_, _, _)).Times(0);
243
244- ALOG(LOG_VERBOSE, NULL, verbose);
245+ ALOG(LOG_VERBOSE, NULL, verbose);
246 }
247
248 TEST_F(InputReport, info_message)
249 {
250 EXPECT_CALL(logger, log(
251 ml::Logger::informational,
252- __PRETTY_FUNCTION__,
253+ "[Foo]Some informational message",
254 component));
255
256- ALOGI(__PRETTY_FUNCTION__);
257+ ALOGI("Some informational message");
258 }
259
260 TEST_F(InputReport, warning_message)
261 {
262 EXPECT_CALL(logger, log(
263 ml::Logger::warning,
264- __PRETTY_FUNCTION__,
265+ "[Foo]Warning!!!",
266 component));
267
268- ALOGW(__PRETTY_FUNCTION__);
269+ ALOGW("Warning!!!");
270 }
271
272 TEST_F(InputReport, error_message)
273 {
274 EXPECT_CALL(logger, log(
275 ml::Logger::error,
276- __PRETTY_FUNCTION__,
277+ "[Foo]An error occurred!",
278 component));
279
280- ALOGE(__PRETTY_FUNCTION__);
281+ ALOGE("An error occurred!");
282 }

Subscribers

People subscribed via source and target branches