Dobby  3.0
Dobby “Docker based Thingy” is a tool for managing and running OCI containers using crun
EthanLogClient.h
1 /*
2 * If not stated otherwise in this file or this component's LICENSE file the
3 * following copyright and licenses apply:
4 *
5 * Copyright 2016 Sky UK
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 /*
20  * File: EthanLogClient.h
21  *
22  */
23 
24 #ifndef ETHANLOGCLIENT_H
25 #define ETHANLOGCLIENT_H
26 
27 #include "ContainerId.h"
28 
29 #include <map>
30 #include <set>
31 #include <chrono>
32 #include <string>
33 #include <cstdint>
34 
35 #include <sys/uio.h>
36 
37 
38 typedef struct sd_event sd_event;
39 typedef struct sd_event_source sd_event_source;
40 
41 
43 {
44 public:
45  EthanLogClient(sd_event *loop, ContainerId &&id, std::string &&name, int fd,
46  unsigned allowedLevels, unsigned rate, unsigned burstSize,
47  const std::string& memCgroupMountPoint);
48  ~EthanLogClient();
49 
50  EthanLogClient(const EthanLogClient &other) = delete;
51  EthanLogClient(EthanLogClient &&other) = delete;
52 
53  EthanLogClient &operator=(const EthanLogClient &other) = delete;
54  EthanLogClient &operator=(EthanLogClient &&other) = delete;
55 
56  void setContainerPid(pid_t pid);
57 
58 public:
59  inline bool closed() const
60  {
61  return (mSource == nullptr);
62  }
63 
64  inline ContainerId id() const
65  {
66  return mContainerId;
67  }
68 
69 public:
70  static constexpr unsigned LOG_LEVEL_FATAL = (0x1 << 0);
71  static constexpr unsigned LOG_LEVEL_ERROR = (0x1 << 1);
72  static constexpr unsigned LOG_LEVEL_WARNING = (0x1 << 2);
73  static constexpr unsigned LOG_LEVEL_MILESTONE = (0x1 << 3);
74  static constexpr unsigned LOG_LEVEL_INFO = (0x1 << 4);
75  static constexpr unsigned LOG_LEVEL_DEBUG = (0x1 << 5);
76 
77 private:
78  static int pipeFdHandler(sd_event_source *source, int fd,
79  uint32_t revents, void *userData);
80 
81  int pipeFdHandler(uint32_t revents);
82 
83  void processLogData();
84  int processLogLevel(const char *field, ssize_t len, struct iovec *iov) const;
85 #if (AI_BUILD_TYPE == AI_DEBUG)
86  int processPid(const char *field, ssize_t len, struct iovec *iov) const;
87 #endif
88  int processTimestamp(const char *field, ssize_t len, struct iovec *iov) const;
89  int processThreadName(const char *field, ssize_t len, struct iovec *iov) const;
90  int processCodeFile(const char *field, ssize_t len, struct iovec *iov) const;
91  int processCodeFunction(const char *field, ssize_t len, struct iovec *iov) const;
92  int processCodeLine(const char *field, ssize_t len, struct iovec *iov) const;
93  int processMessage(const char *field, ssize_t len, struct iovec *iov) const;
94 
95  bool shouldDrop();
96 
97 #if (AI_BUILD_TYPE == AI_DEBUG)
98  pid_t findRealPid(pid_t nsPid) const;
99  std::set<pid_t> getAllContainerPids() const;
100  pid_t readNsPidFromProc(pid_t pid) const;
101 #endif // (AI_BUILD_TYPE == AI_DEBUG)
102 
103  static constexpr ssize_t MAX_LOG_MSG_LENGTH = 512;
104 
105  static constexpr char RECORD_DELIM = '\x1e';
106  static constexpr char FIELD_DELIM = '\x1f';
107 
108 private:
109  const ContainerId mContainerId;
110  const std::string mName;
111  const int mPipeFd;
112  const unsigned mAllowedLevels;
113 
114  sd_event_source *mSource;
115 
116  std::string mIdentifier;
117 
118  char mMsgBuf[(MAX_LOG_MSG_LENGTH * 2)];
119  size_t mMsgLen;
120 
121  bool mRateLimitingEnabled;
122 
123  struct TokenBucket
124  {
125  const unsigned int rate;
126  const unsigned int burstSize;
127 
128  unsigned int tokens;
129  std::chrono::steady_clock::time_point lastFill;
130 
131  TokenBucket(unsigned int rate_, unsigned int burstSize_)
132  : rate(rate_)
133  , burstSize(burstSize_)
134  , tokens(0)
135  , lastFill(std::chrono::steady_clock::time_point::min())
136  { }
137 
138  } mTokenBucket;
139 
140  unsigned int mDropped;
141  std::chrono::steady_clock::time_point mFirstDropped;
142  std::chrono::steady_clock::time_point mLastDropped;
143 
144  std::string mDefaultObjectPid;
145  std::string mDefaultSyslogPid;
146 
147  std::string mCgroupPidsPath;
148  mutable std::map<pid_t, pid_t> mNsToRealPidMapping;
149 
150 };
151 
152 
153 #endif // ETHANLOGCLIENT_H
A wrapper around a std::string, used to add some type definition to to an id and also to sanity check...
Definition: ContainerId.h:41
Definition: EthanLogClient.h:43
int processPid(const char *field, ssize_t len, struct iovec *iov) const
Process the pid field.
Definition: EthanLogClient.cpp:733
EthanLogClient(sd_event *loop, ContainerId &&id, std::string &&name, int fd, unsigned allowedLevels, unsigned rate, unsigned burstSize, const std::string &memCgroupMountPoint)
Constructs a logging client which represents one pipe.
Definition: EthanLogClient.cpp:64
void setContainerPid(pid_t pid)
Sets the base pid for the client's container.
Definition: EthanLogClient.cpp:128
int processCodeFunction(const char *field, ssize_t len, struct iovec *iov) const
Process the function name field.
Definition: EthanLogClient.cpp:844
int processTimestamp(const char *field, ssize_t len, struct iovec *iov) const
Process the timestamp field.
Definition: EthanLogClient.cpp:695
std::set< pid_t > getAllContainerPids() const
Reads the set of all pids within the client's container.
Definition: EthanLogClient.cpp:964
static int pipeFdHandler(sd_event_source *source, int fd, uint32_t revents, void *userData)
Callback called when data to read on the logging pipe.
Definition: EthanLogClient.cpp:150
int processThreadName(const char *field, ssize_t len, struct iovec *iov) const
Process the thread name field.
Definition: EthanLogClient.cpp:794
int processMessage(const char *field, ssize_t len, struct iovec *iov) const
Process the message field.
Definition: EthanLogClient.cpp:712
pid_t readNsPidFromProc(pid_t pid) const
Given a pid (in global namespace) tries to find what it's namespace pid is.
Definition: EthanLogClient.cpp:1009
int processCodeLine(const char *field, ssize_t len, struct iovec *iov) const
Process the line number field.
Definition: EthanLogClient.cpp:814
pid_t findRealPid(pid_t nsPid) const
Attempts to find the pid number in the root pid namespace from a pid in the containers namespace.
Definition: EthanLogClient.cpp:906
void processLogData()
Process some log data from a client pipe.
Definition: EthanLogClient.cpp:389
int processLogLevel(const char *field, ssize_t len, struct iovec *iov) const
Process the log level field.
Definition: EthanLogClient.cpp:642
bool shouldDrop()
Returns true if the message should be dropped due to rate limiting.
Definition: EthanLogClient.cpp:297
int processCodeFile(const char *field, ssize_t len, struct iovec *iov) const
Process the function name field.
Definition: EthanLogClient.cpp:864
Definition: EthanLogClient.h:124