This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Add -log=public to redact all request info from index server logs
ClosedPublic

Authored by sammccall on Oct 31 2020, 3:30 AM.

Details

Summary

The index server has access to potentially-sensitive information, e.g. a
sequence of fuzzyFind requests reveals details about code completions in the
editor which in turn reveals details about the code being edited.
This information is necessary to provide the service, and our intention[1] is it
should never be retained beyond the scope of the request (e.g. not logged).

At the same time, some log messages should be exposed:

  • server startup/index reloads etc that don't pertain to a user request
  • basic request logs (method, latency, #results, error code) for monitoring
  • errors while handling requests, without request-specific data

The -log=public design accommodates these by allowing three types of logs:

  • those not associated with any user RPC request (via context-propagation)
  • those explicitly tagged as [public] in the log line
  • logging of format strings only, with no interpolated data (error level only)

[1] Specifically: Google is likely to run public instances of this server
for LLVM and potentially other projects, they will run in this configuration.
The details agreed in a Google-internal privacy review.
As clangd developers, we'd encourage others to use this configuration for public
instances too.

Diff Detail

Event Timeline

sammccall created this revision.Oct 31 2020, 3:30 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 31 2020, 3:30 AM
sammccall requested review of this revision.Oct 31 2020, 3:30 AM

Couple of notes on this patch.

There's no actual request logging here yet. My plan is something like [public] request v1/Relations => SUCCESS: 3 results in 3ms. Wanted to keep the patch a reasonable size.

There's also no testing, testing is definitely important here. I want to build something on top of Kirill's python tests once that lands. Probably in the patch that adds request logging.

The [public] thing is gross, but I think worse is better here.
I went through lots of iterations, including with explicit "Sensitivity" enum passed around, but it was pretty invasive.
Moreover explicitly supporting it in Logger.h made me feel like all the callsites in all our libraries should consider whether info is public or not. I think spreading that cognitive load around the whole project is a net negative.
With the request-context detection (which was a last-minute realization actually), maybe we could even get away without [public], but I didn't want to commit to contorting our code so that the request logging happens outside the request scope. Happy to drop this part if you think we can make it work.

Weird extension idea: we could have a completely synthetic request ID to stick on the request log lines and also the pattern-only elog()s to tie them together.

Changing the Logger API is a bit annoying, but has one side-benefit: error count grouped by format string is a nice thing to be able to monitor.

Thanks for figuring this one out!

I think the final result looks pretty good, I especially loved only disabling when there's a request in question.
My only hesitation is around logging all severities when we are outside a request, I suppose it shouldn't cause too much trouble but we sometimes end up logging too much in verbose mode and I am afraid of this hindering the server performance at random intervals (e.g. when it loads a new index). But this is just speculation. I suppose we can think about this when it happens. Also maybe we should not be logging that much instead :D

In addition to that it could be nice to see how the public tagging will happen. Are you planning to have a custom endpoint for it, or should the user manually insert it into format string? Both are fine by me, the latter might even make it less error-prone for accidental logging at the cost of misspells and spreading the string across the codebase.

Thanks for figuring this one out!

I think the final result looks pretty good, I especially loved only disabling when there's a request in question.
My only hesitation is around logging all severities when we are outside a request, I suppose it shouldn't cause too much trouble but we sometimes end up logging too much in verbose mode and I am afraid of this hindering the server performance at random intervals (e.g. when it loads a new index). But this is just speculation. I suppose we can think about this when it happens. Also maybe we should not be logging that much instead :D

So I can't remember anymore why I put this as an enum -log=public rather than an independent switch -log-public or so that could combine with any log level.
Sounds like the latter would be better?

In addition to that it could be nice to see how the public tagging will happen. Are you planning to have a custom endpoint for it, or should the user manually insert it into format string? Both are fine by me, the latter might even make it less error-prone for accidental logging at the cost of misspells and spreading the string across the codebase.

Manually insert it into the format string. After thinking about it I came to the conclusion there just aren't that many places where we need to log things publicly. I expect to basically not have any visibility inside most requests except the error patterns.

So I can't remember anymore why I put this as an enum -log=public rather than an independent switch -log-public or so that could combine with any log level.
Sounds like the latter would be better?

Agreed.

Manually insert it into the format string. After thinking about it I came to the conclusion there just aren't that many places where we need to log things publicly. I expect to basically not have any visibility inside most requests except the error patterns.

SG.

kadircet accepted this revision.Nov 2 2020, 6:14 AM
This revision is now accepted and ready to land.Nov 2 2020, 6:14 AM
sammccall updated this revision to Diff 302360.Nov 2 2020, 11:57 AM

Use separate flag for log-public vs log level

This revision was landed with ongoing or failed builds.Nov 2 2020, 12:25 PM
This revision was automatically updated to reflect the committed changes.