mirror of
https://fuchsia.googlesource.com/third_party/pigweed.googlesource.com/pigweed/pigweed
synced 2024-09-20 05:41:06 +00:00
59f3d43da1
- Remove redundant "Service" word from proto service name. - Properly update the packed messages count used in dropped message count. - Replace server writer deprecated open() with active(). No-Docs-Update-Reason: Fixed intended behavior. Change-Id: I045ed50ce2f823909ff555881acc3ecbea3e8d3f Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/61920 Pigweed-Auto-Submit: Carlos Chinchilla <cachinchilla@google.com> Reviewed-by: Wyatt Hepler <hepler@google.com> Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
181 lines
7.2 KiB
Protocol Buffer
181 lines
7.2 KiB
Protocol Buffer
// Copyright 2021 The Pigweed Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
// use this file except in compliance with the License. You may obtain a copy of
|
|
// the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations under
|
|
// the License.
|
|
|
|
syntax = "proto3";
|
|
|
|
package pw.log;
|
|
|
|
import "pw_tokenizer/proto/options.proto";
|
|
|
|
option java_outer_classname = "Log";
|
|
|
|
// A log message and metadata. Logs come in a few different forms:
|
|
//
|
|
// 1. A tokenized log message (recommended for production)
|
|
// 2. A non-tokenized log message (good for development)
|
|
// 3. A "log missed" tombstone, indicating that some logs were dropped
|
|
//
|
|
// Size analysis for tokenized log messages, including each field's proto tag:
|
|
//
|
|
// - message - 6-12 bytes, depending on number and value of arguments
|
|
// - line_level - 3 bytes; 4 bytes if line > 2048 (uncommon)
|
|
// - timestamp - 3 bytes; assuming delta encoding
|
|
// - thread_name - 6 bytes
|
|
//
|
|
// Adding the fields gives the total proto message size:
|
|
//
|
|
// 6-12 bytes - log
|
|
// 9-15 bytes - log + level + line
|
|
// 12-18 bytes - log + level + line + timestamp
|
|
//
|
|
// An analysis of a project's log token database revealed the following
|
|
// distribution of the number of arguments to log messages:
|
|
//
|
|
// # args # messages
|
|
// 0 2,700
|
|
// 1 2,400
|
|
// 2 1,200
|
|
// 3+ 1,000
|
|
//
|
|
// Note: The below proto makes some compromises compared to what one might
|
|
// expect for a "clean" proto design, in order to shave bytes off of the
|
|
// messages. It is critical that the log messages are as small as possible to
|
|
// enable storing more logs in limited memory. This is why, for example, there
|
|
// is no separate "DroppedLog" type, or a "TokenizedLog" and "StringLog", which
|
|
// would add at least 2 extra bytes per message
|
|
message LogEntry {
|
|
// The log message, which may be tokenized.
|
|
//
|
|
// If tokenized logging is used, implementations may encode metadata in the
|
|
// log message rather than as separate proto fields. This reduces the size of
|
|
// the protobuf with no overhead.
|
|
//
|
|
// The standard format for encoding metadata in the log message is defined by
|
|
// the pw_log_tokenized module. The message and metadata are encoded as
|
|
// key-value pairs using ■ and ♦ as delimiters. For example:
|
|
//
|
|
// ■msg♦This is the log message: %d■module♦wifi■file♦../path/to/file.cc
|
|
//
|
|
// See http://pigweed.dev/pw_log_tokenized for full details. When
|
|
// pw_log_tokenized is used, this metadata is automatically included as
|
|
// described.
|
|
//
|
|
// The level and flags are not included since they may be runtime values and
|
|
// thus cannot always be tokenized. The line number is not included because
|
|
// line numbers change frequently and a new token is created for each line.
|
|
//
|
|
// Size analysis when tokenized:
|
|
//
|
|
// tag+wire = 1 byte
|
|
// size = 1 byte; payload will almost always be < 127 bytes
|
|
// payload = N bytes; typically 4-10 in practice
|
|
//
|
|
// Total: 2 + N ~= 6-12 bytes
|
|
optional bytes message = 1 [(tokenizer.format) = TOKENIZATION_OPTIONAL];
|
|
|
|
// Packed log level and line number. Structure:
|
|
//
|
|
// Level: Bottom 3 bits; level = line_level & 0x7
|
|
// Line: Remaining bits; line = (line_level >> 3)
|
|
//
|
|
// Note: This packing saves two bytes per log message in most cases compared
|
|
// to having line and level separately; and is zero-cost if the log backend
|
|
// omits the line number.
|
|
optional uint32 line_level = 2;
|
|
|
|
// Some log messages have flags to indicate attributes such as whether they
|
|
// are from an assert or if they contain PII. The particular flags are
|
|
// product- and implementation-dependent.
|
|
optional uint32 flags = 3;
|
|
|
|
// Timestamps are either specified with an absolute timestamp or relative to
|
|
// the previous log entry.
|
|
oneof time {
|
|
// The absolute timestamp in implementation-defined ticks. Applications
|
|
// determine how to interpret this on the receiving end. In the simplest
|
|
// case, these ticks might be milliseconds or microseconds since boot.
|
|
// Applications could also access clock information out-of-band with a
|
|
// ClockParameters protobuf.
|
|
int64 timestamp = 4;
|
|
|
|
// Time since the last entry in implementation-defined ticks, as for the
|
|
// timestamp field. This enables delta encoding when batching entries
|
|
// together.
|
|
//
|
|
// Size analysis for this field including tag and varint, assuming 1 kHz
|
|
// ticks:
|
|
//
|
|
// < 127 ms gap == 127 ms == 7 bits == 2 bytes
|
|
// < 16,000 ms gap == 16 seconds == 14 bits == 3 bytes
|
|
// < 2,000,000 ms gap == 35 minutes == 21 bits == 4 bytes
|
|
// < 300,000,000 ms gap == 74 hours == 28 bits == 5 bytes
|
|
//
|
|
// Log bursts will thus consume just 2 bytes (tag + up to 127ms delta) for
|
|
// the timestamp, which is a good improvement over an absolute timestamp.
|
|
int64 time_since_last_entry = 5;
|
|
}
|
|
|
|
// The following fields are planned but will not be added until they are
|
|
// needed. Protobuf field numbers over 15 use an extra byte, so these fields
|
|
// are left out for now to avoid reserving field numbers unnecessarily.
|
|
|
|
// When the log buffers are full but more logs come in, the logs are counted
|
|
// and a special log message is omitted with only counts for the number of
|
|
// messages dropped. The timestamp indicates the time that the "missed logs"
|
|
// message was inserted into the queue.
|
|
//
|
|
// As an alternative to these fields, implementations may simply send a
|
|
// message stating the drop count.
|
|
// optional uint32 dropped = ?;
|
|
// optional uint32 dropped_warning_or_above = ?;
|
|
|
|
// Represents the device from which the log originated. The meaning of this
|
|
// field is implementation defined
|
|
// optional uint32 source_id = ?;
|
|
|
|
// The task or thread name that created the log message. If the log was not
|
|
// created on a thread, it should use a name appropriate to that context.
|
|
// optional bytes thread_name = ?
|
|
// [(tokenizer.format) = TOKENIZATION_OPTIONAL];
|
|
|
|
// The file path where this log was created, if not encoded in the message.
|
|
// optional bytes file = ? [(tokenizer.format) = TOKENIZATION_OPTIONAL];
|
|
|
|
// The PW_LOG_MODULE_NAME for this log message, if it is not encoded in the
|
|
// message.
|
|
// optional bytes module_name = ?
|
|
// [(tokenizer.format) = TOKENIZATION_OPTIONAL];
|
|
|
|
// Some messages are associated with trace events, which may carry additional
|
|
// contextual data. This is a tuple of a data format string which could be
|
|
// used by the decoder to identify the data (e.g. printf-style tokens) and the
|
|
// data itself in bytes.
|
|
// optional bytes data_format = ?
|
|
// [(tokenizer.format) = TOKENIZATION_OPTIONAL];
|
|
// optional bytes data = ?;
|
|
}
|
|
|
|
message LogRequest {
|
|
// This will include fields for configuring log filtering.
|
|
}
|
|
|
|
message LogEntries {
|
|
repeated LogEntry entries = 1;
|
|
}
|
|
|
|
// RPC service for accessing logs.
|
|
service Logs {
|
|
rpc Listen(LogRequest) returns (stream LogEntries);
|
|
}
|