• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "log_kmsg.h"
17 #include <cstdlib>
18 #include <cinttypes>
19 #include <iostream>
20 #include <string>
21 #include <thread>
22 #include <fstream>
23 #include <sys/klog.h>
24 #include <sys/syslog.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include "hilog/log.h"
29 #include "init_file.h"
30 
31 namespace OHOS {
32 namespace HiviewDFX {
33 using namespace std;
34 
LinuxReadOneKmsg(KmsgParser & parser)35 ssize_t LogKmsg::LinuxReadOneKmsg(KmsgParser& parser)
36 {
37     std::vector<char> kmsgBuffer(BUFSIZ, '\0');
38     ssize_t size = -1;
39     do {
40         size = read(kmsgCtl, kmsgBuffer.data(), BUFSIZ - 1);
41     } while (size < 0 && errno == EPIPE);
42     if (size > 0) {
43         std::optional<HilogMsgWrapper> msgWrap = parser.ParseKmsg(kmsgBuffer);
44         if (msgWrap.has_value()) {
45             size_t result = hilogBuffer.Insert(msgWrap->GetHilogMsg());
46             if (result <= 0) {
47                 return result;
48             }
49         }
50     }
51     return size;
52 }
53 
LinuxReadAllKmsg()54 int LogKmsg::LinuxReadAllKmsg()
55 {
56     ssize_t rdFailTimes = 0;
57     const ssize_t maxFailTime = 10;
58     kmsgCtl = GetControlFile("/dev/kmsg");
59     if (kmsgCtl < 0) {
60         std::cout << "Cannot open kmsg! ";
61         HilogPrintError(errno);
62         return -1;
63     }
64     std::unique_ptr<KmsgParser> parser = std::make_unique<KmsgParser>();
65     while (true) {
66         ssize_t sz = LinuxReadOneKmsg(*parser);
67         if (sz < 0) {
68             rdFailTimes++;
69             if (maxFailTime < rdFailTimes) {
70                 std::cout << "Read kmsg failed more than maxFailTime" << std::endl;
71                 return -1;
72             }
73             sleep(1);
74             continue;
75         }
76         rdFailTimes = 0;
77     }
78     return 1;
79 }
80 
ReadAllKmsg()81 void LogKmsg::ReadAllKmsg()
82 {
83 #ifdef __linux__
84     std::cout << "Platform: Linux" << std::endl;
85     LinuxReadAllKmsg();
86 #endif
87 }
88 
Start()89 void LogKmsg::Start()
90 {
91     std::thread KmsgThread([this]() {
92         ReadAllKmsg();
93     });
94     KmsgThread.join();
95 }
96 
~LogKmsg()97 LogKmsg::~LogKmsg()
98 {
99     close(kmsgCtl);
100 }
101 } // namespace HiviewDFX
102 } // namespace OHOS
103 
104