Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration option to output logs in logfmt #1022

Open
wants to merge 11 commits into
base: unstable
Choose a base branch
from

Conversation

azuredream
Copy link

See more disscussion:
redis/redis#12934

Add ability to configure Redis to output logs in logfmt (See https://brandur.org/logfmt) as well as configure timestamp format options to more standard ISO 8601 or unix timestamp.

This change is implemented by two configs:
log-format: Either default or logfmt.
log-timestamp-format: default, iso8601, or unix.

#1006

$ ./valkey-server  /home/zhaoz12/git/valkey/valkey/valkey.conf
pid=109463 role=RDB/AOF timestamp="2024-09-10T20:37:25.738-04:00" level=warning message="WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect."
pid=109463 role=RDB/AOF timestamp="2024-09-10T20:37:25.738-04:00" level=notice message="oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo"
pid=109463 role=RDB/AOF timestamp="2024-09-10T20:37:25.738-04:00" level=notice message="Valkey version=255.255.255, bits=64, commit=affbea5d, modified=1, pid=109463, just started"
pid=109463 role=RDB/AOF timestamp="2024-09-10T20:37:25.738-04:00" level=notice message="Configuration loaded"
pid=109463 role=master timestamp="2024-09-10T20:37:25.738-04:00" level=notice message="monotonic clock: POSIX clock_gettime"
pid=109463 role=master timestamp="2024-09-10T20:37:25.739-04:00" level=warning message="Failed to write PID file: Permission denied"

Copy link

codecov bot commented Sep 12, 2024

Codecov Report

Attention: Patch coverage is 24.07407% with 41 lines in your changes missing coverage. Please review.

Project coverage is 70.65%. Comparing base (262d970) to head (ca0cedf).
Report is 18 commits behind head on unstable.

Files with missing lines Patch % Lines
src/server.c 24.07% 41 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #1022      +/-   ##
============================================
+ Coverage     70.61%   70.65%   +0.03%     
============================================
  Files           114      114              
  Lines         61734    63125    +1391     
============================================
+ Hits          43595    44602    +1007     
- Misses        18139    18523     +384     
Files with missing lines Coverage Δ
src/config.c 78.84% <ø> (+0.14%) ⬆️
src/server.h 100.00% <ø> (ø)
src/server.c 87.67% <24.07%> (-0.97%) ⬇️

... and 89 files with indirect coverage changes

@madolson
Copy link
Member

😀 thanks for opening this, we're working on launching the next version but will take a look shortly.

@PingXie
Copy link
Member

PingXie commented Sep 12, 2024

I like this change. Free-form log lines can be tricky to parse and search, and this feels like a good step toward adopting more structured logging. We could even extend it further to include properties like "area" (e.g., "cluster," "normal replication," "dual channel replication," etc.). Thanks for your work on this, @azuredream!

@madolson madolson added the major-decision-pending Major decision pending by TSC team label Sep 12, 2024
src/server.c Outdated Show resolved Hide resolved
src/server.c Outdated Show resolved Hide resolved
src/server.c Outdated Show resolved Hide resolved
src/server.c Outdated Show resolved Hide resolved
src/server.h Outdated Show resolved Hide resolved
src/server.c Outdated Show resolved Hide resolved
@madolson
Copy link
Member

madolson commented Oct 6, 2024

@valkey-io/core-team Please indicate your vote on this comment. The open questions I still have are if we want to also do the larger investigation before 8.1 launches about also including the component the log was generated from. We also have the JSON format to add on.

Copy link
Contributor

@zuiderkwast zuiderkwast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed this before in the open source redis time. I like it, just a few comments.

It seems that JSON is more popular. We can add that too in another PR.

Configurable time format is good.

src/server.h Outdated Show resolved Hide resolved
src/server.h Outdated Show resolved Hide resolved
src/server.c Outdated Show resolved Hide resolved
src/config.c Outdated
Comment on lines 127 to 129
configEnum log_timestamp_format_enum[] = {{"default", LOG_TIMESTAMP_DEFAULT},
{"iso8601", LOG_TIMESTAMP_ISO8601},
{"unix", LOG_TIMESTAMP_UNIX},
Copy link
Member

@madolson madolson Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
configEnum log_timestamp_format_enum[] = {{"default", LOG_TIMESTAMP_DEFAULT},
{"iso8601", LOG_TIMESTAMP_ISO8601},
{"unix", LOG_TIMESTAMP_UNIX},
configEnum log_timestamp_format_enum[] = {{"legacy", LOG_TIMESTAMP_LEGACY},
{"iso8601", LOG_TIMESTAMP_ISO8601},
{"milliseconds", LOG_TIMESTAMP_MILLISECONDS},

@azuredream Was there a reason we added the unix milliseconds timestamp option? While discussing it, we weren't sure if it was needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(@madolson The PR currently emits it as seconds, not milliseconds, since the epoch.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want the epoch, I think millisecond timestamp makes a lot more sense. A lot of important events happen sub-second.

@madolson madolson added major-decision-approved Major decision approved by TSC team and removed major-decision-pending Major decision pending by TSC team labels Oct 7, 2024
src/server.c Outdated
snprintf(buf + off, sizeof(buf) - off, "%03d%s", (int)tv.tv_usec / 1000, tzbuf);
break;

case LOG_TIMESTAMP_UNIX: snprintf(buf, sizeof(buf), "%ld", tv.tv_sec); break;
Copy link
Member

@madolson madolson Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be in milliseconds, not seconds.

@azuredream
Copy link
Author

@madolson @zuiderkwast
PR updated as you suggested.
Thanks for reviewing.

@azuredream
Copy link
Author

azuredream commented Oct 12, 2024

Demo logs:

log-format logfmt
log-timestamp-format milliseconds

pid=557888 role=RDB/AOF timestamp="1728757076.562" level=notice message="oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo"

log-format legacy
log-timestamp-format milliseconds

558253:C 1728757310.034 * oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo

log-format logfmt
log-timestamp-format iso8601

pid=558427 role=RDB/AOF timestamp="2024-10-12T14:24:28.141-04:00" level=notice message="oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo"

log-format legacy
log-timestamp-format iso8601

558523:C 2024-10-12T14:24:57.923-04:00 * oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo

log-format logfmt
log-timestamp-format legacy

pid=558599 role=RDB/AOF timestamp="12 Oct 2024 14:25:59.813" level=notice message="oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo"

log-format legacy
log-timestamp-format legacy

558689:C 12 Oct 2024 14:26:30.872 * oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo

src/server.c Outdated Show resolved Hide resolved
src/server.c Outdated Show resolved Hide resolved
@madolson madolson self-requested a review October 15, 2024 04:41
src/server.c Outdated
/* Low level logging. To use only for very big messages, otherwise
* serverLog() is to prefer. */
void serverLogRaw(int level, const char *msg) {
void serverLogRaw(int level, char *msg) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutability modified.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... I hope this works. I see many places in the code where this function is called with a string literal, like

serverLogRaw(LL_WARNING, "Failed applying new module configuration. Restoring previous settings.");

This can't be mutable, I think...

src/server.c Outdated
Comment on lines 140 to 146
while (msg[src] != '\0') {
if (msg[src] == '"') {
msg[dst++] = '\'';
} else if (msg[src] != '\n' && msg[src] != '\r') {
msg[dst++] = msg[src];
}
src++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea: If we replace \r and \n with a space instead, then we don't need to copy/move the rest of the string. We don't need the dst index.

Suggested change
while (msg[src] != '\0') {
if (msg[src] == '"') {
msg[dst++] = '\'';
} else if (msg[src] != '\n' && msg[src] != '\r') {
msg[dst++] = msg[src];
}
src++;
while (msg[src] != '\0') {
if (msg[src] == '"') {
msg[src] = '\'';
} else if (msg[src] == '\n' && msg[src] == '\r') {
msg[src] = ' ';
}
src++;

src/server.c Outdated Show resolved Hide resolved
@azuredream
Copy link
Author

Code updateded.

src/server.c Outdated Show resolved Hide resolved
Copy link
Contributor

@zuiderkwast zuiderkwast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me now.

One of the commits is missing sign-off. See the Details link on the DCO CI job. Can you fix it? You can squash and force-push as you want.

See also the clang-format CI job. It's a trailing whitespace on one line.

Is the Valkey logo logged on startup? It must look very weird with logfmt?

} else {
role_char = (server.primary_host ? 'S' : 'M'); /* replica or Primary. */
role_index = (server.primary_host ? 2 : 3); /* Slave or Master. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We should avoid slave and master even in comments.

Suggested change
role_index = (server.primary_host ? 2 : 3); /* Slave or Master. */
role_index = (server.primary_host ? 2 : 3); /* replica or primary. */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major-decision-approved Major decision approved by TSC team
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

4 participants