You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
6.4 KiB
166 lines
6.4 KiB
// Copyright 2020 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 = "proto2";
|
|
|
|
package pw.log;
|
|
|
|
option java_package = "pw.rpc.proto";
|
|
option java_outer_classname = "Log";
|
|
|
|
// A log with a tokenized message, a string message, or dropped indicator. A
|
|
// message can be one of three types:
|
|
//
|
|
// 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 in the common case; including the proto tag for
|
|
// the field (so adding the fields gives the total proto message size):
|
|
//
|
|
// - message_tokenized - 6-12 bytes, depending on # and value of arguments
|
|
// - line_level - 3 bytes; 4 bytes if line > 2048 (uncommon)
|
|
// - timestamp - 3 bytes; assuming delta encoding
|
|
// - thread_tokenized - 3 bytes
|
|
//
|
|
// Total:
|
|
//
|
|
// 6-12 bytes - log
|
|
// 9-15 bytes - log + level + line
|
|
// 12-18 bytes - log + level + line + timestamp
|
|
// 15-21 bytes - log + level + line + timestamp + task
|
|
//
|
|
// 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
|
|
// Note: Time-related fields will likely support specifying the time as a ratio
|
|
// (period) and an absolute time separate from the current delta fields.
|
|
message LogEntry {
|
|
// The tokenized log message. Internally, the format has a 32-bit token
|
|
// followed by the arguments for that message. The unformatted log string
|
|
// corresponding to the token in the token database must follow this format:
|
|
//
|
|
// file|module|message
|
|
//
|
|
// For example:
|
|
//
|
|
// ../boot/bluetooth.cc|BOOT|Bluetooth is on the fritz; error code: %d
|
|
//
|
|
// Note: The level and flags are not included since level and flags are
|
|
// runtime values and so cannot be tokenized.
|
|
//
|
|
// Size analysis:
|
|
//
|
|
// 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_tokenized = 1;
|
|
|
|
// 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 for example assert or PII. The
|
|
// particular flags are product- and implementation-dependent. When no flags
|
|
// are present, the field is omitted entirely.
|
|
optional uint32 flags = 3;
|
|
|
|
// The task or thread that created the log message.
|
|
//
|
|
// In practice, the task token and tag should be just 3 bytes, since a 14 bit
|
|
// token for the task name should be enough.
|
|
optional uint32 thread_tokenized = 4;
|
|
|
|
// Timestamp. Note: The units here are TBD and will likely require a separate
|
|
// mechanism to indicate units. This field is likely to change as we figure
|
|
// out the right strategy for timestamps in Pigweed. This is a variable-sized
|
|
// integer to enable scaling this up to a uint64 later on without impacting
|
|
// the wire format.
|
|
optional int64 timestamp = 5;
|
|
|
|
// Time since the last entry. Generally, one of timestamp or this field will
|
|
// be specified. This enables delta encoding when batching entries together.
|
|
//
|
|
// Size analysis for this field including tag and varint:
|
|
//
|
|
// < 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 timestamp in many cases.
|
|
// Note: The units of this field are TBD and will likely require a separate
|
|
// mechanism to indicate units. The calculations above assume milliseconds
|
|
// and may change if the units differ.
|
|
optional int64 elapsed_time_since_last_entry = 6;
|
|
|
|
// Fully formatted textual log message.
|
|
optional string message_string = 16;
|
|
|
|
// For non-tokenized logging, the file name.
|
|
optional string file = 17;
|
|
|
|
// String representation of the task that created the log message.
|
|
optional string thread_string = 18;
|
|
|
|
// 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.
|
|
//
|
|
// Missed logs messages will only have one of the timestamp fields and these
|
|
// counters specified.
|
|
optional uint32 dropped = 19;
|
|
optional uint32 dropped_warning_or_above = 20;
|
|
|
|
// 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 string data_format_string = 21;
|
|
optional bytes data = 22;
|
|
}
|
|
|
|
message LogRequest {}
|
|
message LogEntries {
|
|
repeated LogEntry entries = 1;
|
|
}
|
|
|
|
service Logs {
|
|
rpc Get(LogRequest) returns (stream LogEntries) {}
|
|
}
|