diff options
author | Mark Salyzyn | 2014-02-26 11:50:16 -0600 |
---|---|---|
committer | Mark Salyzyn | 2014-02-26 11:52:35 -0600 |
commit | 0175b0747a1f55329109e84c9a1322dcb95e2848 (patch) | |
tree | a48dd103279c3efc313028a09fb4570d212e624d /logd/LogReader.cpp | |
parent | 9b986497e7f19a7fde9e35eb73d765f4a09dee07 (diff) | |
download | platform-system-core-0175b0747a1f55329109e84c9a1322dcb95e2848.tar.gz platform-system-core-0175b0747a1f55329109e84c9a1322dcb95e2848.tar.xz platform-system-core-0175b0747a1f55329109e84c9a1322dcb95e2848.zip |
logd: initial checkin.
* Create a new userspace log daemon for handling logging messages.
Original-Change-Id: I75267df16359684490121e6c31cca48614d79856
Signed-off-by: Nick Kralevich <nnk@google.com>
* Merge conflicts
* rename new syslog daemon to logd to prevent confusion with bionic syslog
* replace racy getGroups call with KISS call to client->getGid()
* Timestamps are filed at logging source
* insert entries into list in timestamp order
* Added LogTimeEntry tail filtration handling
* Added region locking around LogWriter list
* separate threads for each writer
* /dev/socket/logd* permissions
Signed-off-by: Mark Salyzyn <salyzyn@google.com>
(cherry picked from commit 3e76e0a49760c4970b7cda6153e51026af98e4f3)
Author: Nick Kralevich <nnk@google.com>
Change-Id: Ice88b1412d8f9daa7f9119b2b5aaf684a5e28098
Diffstat (limited to 'logd/LogReader.cpp')
-rw-r--r-- | logd/LogReader.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp new file mode 100644 index 000000000..5b540bf5d --- /dev/null +++ b/logd/LogReader.cpp | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012-2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <poll.h> | ||
18 | #include <sys/socket.h> | ||
19 | #include <cutils/sockets.h> | ||
20 | |||
21 | #include "LogReader.h" | ||
22 | #include "FlushCommand.h" | ||
23 | |||
24 | LogReader::LogReader(LogBuffer *logbuf) | ||
25 | : SocketListener("logdr", true) | ||
26 | , mLogbuf(*logbuf) | ||
27 | { } | ||
28 | |||
29 | // When we are notified a new log entry is available, inform | ||
30 | // all of our listening sockets. | ||
31 | void LogReader::notifyNewLog() { | ||
32 | FlushCommand command(*this); | ||
33 | runOnEachSocket(&command); | ||
34 | } | ||
35 | |||
36 | bool LogReader::onDataAvailable(SocketClient *cli) { | ||
37 | char buffer[255]; | ||
38 | |||
39 | int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1); | ||
40 | if (len <= 0) { | ||
41 | doSocketDelete(cli); | ||
42 | return false; | ||
43 | } | ||
44 | buffer[len] = '\0'; | ||
45 | |||
46 | unsigned long tail = 0; | ||
47 | static const char _tail[] = " tail="; | ||
48 | char *cp = strstr(buffer, _tail); | ||
49 | if (cp) { | ||
50 | tail = atol(cp + sizeof(_tail) - 1); | ||
51 | } | ||
52 | |||
53 | unsigned int logMask = -1; | ||
54 | static const char _logIds[] = " lids="; | ||
55 | cp = strstr(buffer, _logIds); | ||
56 | if (cp) { | ||
57 | logMask = 0; | ||
58 | cp += sizeof(_logIds) - 1; | ||
59 | while (*cp && *cp != '\0') { | ||
60 | int val = 0; | ||
61 | while (('0' <= *cp) && (*cp <= '9')) { | ||
62 | val *= 10; | ||
63 | val += *cp - '0'; | ||
64 | ++cp; | ||
65 | } | ||
66 | logMask |= 1 << val; | ||
67 | if (*cp != ',') { | ||
68 | break; | ||
69 | } | ||
70 | ++cp; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | pid_t pid = 0; | ||
75 | static const char _pid[] = " pid="; | ||
76 | cp = strstr(buffer, _pid); | ||
77 | if (cp) { | ||
78 | pid = atol(cp + sizeof(_pid) - 1); | ||
79 | } | ||
80 | |||
81 | bool nonBlock = false; | ||
82 | if (strncmp(buffer, "dumpAndClose", 12) == 0) { | ||
83 | nonBlock = true; | ||
84 | } | ||
85 | |||
86 | FlushCommand command(*this, nonBlock, tail, logMask, pid); | ||
87 | command.runSocketCommand(cli); | ||
88 | return true; | ||
89 | } | ||
90 | |||
91 | void LogReader::doSocketDelete(SocketClient *cli) { | ||
92 | LastLogTimes × = mLogbuf.mTimes; | ||
93 | LogTimeEntry::lock(); | ||
94 | LastLogTimes::iterator it = times.begin(); | ||
95 | while(it != times.end()) { | ||
96 | LogTimeEntry *entry = (*it); | ||
97 | if (entry->mClient == cli) { | ||
98 | times.erase(it); | ||
99 | entry->release_Locked(); | ||
100 | break; | ||
101 | } | ||
102 | it++; | ||
103 | } | ||
104 | LogTimeEntry::unlock(); | ||
105 | } | ||