• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_system_private/log.h"
16 
17 #include <array>
18 #include <cstddef>
19 
20 #include "pw_log_rpc/rpc_log_drain.h"
21 #include "pw_log_rpc/rpc_log_drain_map.h"
22 #include "pw_multisink/multisink.h"
23 #include "pw_sync/lock_annotations.h"
24 #include "pw_sync/mutex.h"
25 #include "pw_system/config.h"
26 #include "pw_system/rpc_server.h"
27 
28 namespace pw::system {
29 namespace {
30 
31 using log_rpc::RpcLogDrain;
32 
33 // Storage container for MultiSink used for deferred logging.
34 std::array<std::byte, PW_SYSTEM_LOG_BUFFER_SIZE> log_buffer;
35 
36 // To save RAM, share the mutex and buffer between drains, since drains are
37 // flushed sequentially.
38 sync::Mutex drains_mutex;
39 
40 // Buffer to decode and remove entries from log buffer, to send to a drain.
41 //
42 // TODO(amontanez): pw_log_rpc should provide a helper for this since there's
43 // proto encoding overhead unaccounted for here.
44 static_assert(rpc::MaxSafePayloadSize() >= PW_SYSTEM_MAX_LOG_ENTRY_SIZE);
45 std::array<std::byte, PW_SYSTEM_MAX_LOG_ENTRY_SIZE> log_decode_buffer
46     PW_GUARDED_BY(drains_mutex);
47 
48 std::array<RpcLogDrain, 1> drains{{
49     RpcLogDrain(kDefaultRpcChannelId,
50                 log_decode_buffer,
51                 drains_mutex,
52                 RpcLogDrain::LogDrainErrorHandling::kIgnoreWriterErrors),
53 }};
54 
55 log_rpc::RpcLogDrainMap drain_map(drains);
56 
57 constexpr size_t kMaxPackedLogMessagesSize = rpc::MaxSafePayloadSize();
58 std::array<std::byte, kMaxPackedLogMessagesSize> log_packing_buffer;
59 
60 }  // namespace
61 
62 // Deferred log buffer, for storing log entries while logging_thread_ streams
63 // them independently.
GetMultiSink()64 multisink::MultiSink& GetMultiSink() {
65   static multisink::MultiSink multisink(log_buffer);
66   return multisink;
67 }
68 
GetLogThread()69 log_rpc::RpcLogDrainThread& GetLogThread() {
70   static log_rpc::RpcLogDrainThread logging_thread(
71       GetMultiSink(), drain_map, log_packing_buffer);
72   return logging_thread;
73 }
74 
GetLogService()75 log_rpc::LogService& GetLogService() {
76   static log_rpc::LogService log_service(drain_map);
77   return log_service;
78 }
79 
80 }  // namespace pw::system
81