Git Product home page Git Product logo

readlogs's Introduction

Readlogs

Readlogs is an unofficial web app for viewing Signal debug logs without manually downloading or unarchiving them.

To use it, create a debug log via the Signal app on your device as described in this support article, then open readlogs.pages.dev and paste the URL there.

Current functionality

  • View information and logs from various sections of debug logs, formatted as tables.
  • Search logs by setting a minimum log level (e.g. "Warn" to show warnings, errors, and more important log entries, if any) as well as using a (case-insensitive) search query.
  • View and download raw debug log files in plaintext (i.e. unarchived).

Notable behavior

  • Log entries that span multiple lines (without introducing a new timestamp and other metadata) are assumed to be one log entry.
  • In case of Signal Android, sometimes multiple consecutive log lines repeat the exact same timestamp and metadata. These are collapsed into one entry.
  • Some Signal iOS log entries don't seem to have a log level; it's assumed to be LogLevel::Info.

Overview

This repository primarily contains two pieces of software:

How it works

1. Parsing the debug log URL

All debug log URLs have one of the below formats. The provided URL is parsed before fetching in order catch any potential copy/paste mistakes earlier, thus minimizing requests to the worker.

https://debuglogs.org/{key}{ext?}
https://debuglogs.org/{platform}/{version}/{key}{ext?}
  • platform is ios for Signal iOS, desktop for Signal Desktop, and android for Signal Android.
  • version is the Signal app's version.
  • key is a 64-character string consisting of a-f and 0-9.
  • ext is .zip for Signal iOS, .gz for Signal Desktop, and none for Signal Android.

2. Fetching

In general, the file is fetched using the worker: it's not possible to fetch directly from debuglogs.org due to its Cross-Origin Resource Sharing policy.

There are some differences in the fetching process between Signal Android/Desktop and Signal iOS due to the underlying format that debug logs are uploaded in by the Signal apps:

  • Signal Android/Desktop

    The file is gzip-ped plain text. The worker alters the response received from debuglogs.org to indicate this. The web app itself doesn't handle the decompression of the response from the worker (presumably, the browser or its fetch API performs it); the web app receives the debug log in plain text.

  • Signal iOS

    The file is a zip archive containing multiple files. The worker delivers it unmodified, and the web app itself handles the decompression.

3. Parsing and displaying

Each file (there is one for Signal Android/Desktop, but multiple in case of Signal iOS) is parsed by the web app immediately after fetching.

Note: Signal Desktop can output each log entry in a structured JSON format (if you start it from a terminal and look at the output), however the file submitted to debuglogs.org has the log in plaintext format, which is what this projects parses.

Privacy considerations

Note that debug logs uploaded by the Signal apps already have sensitive information redacted.

Inferring whether anyone viewed a given debug log

It could be possible to infer that someone has recently viewed a given debug log using this project because of different response times due to potential additional cache (compared to just downloading from debuglogs.org) being hit or missed, etc.

There are multiple caching layers present:

  1. debuglogs.org's own cache:

    The behavior of this cache can't be changed by this project. This is also the cache that has an impact in any case, even if you download debug logs from debuglogs.org directly. Though depending on its setup, this cache may be more likely to trigger if the request comes from a certain edge data center of Cloudflare's network (which is the case with this project) because the same data center may be used for multiple users.

  2. Cloudflare's caching of the fetch call in the worker (that requests the debug log from debuglogs.org):

    This cache appears to be enabled, based on the cf-cache-status, age, and last-modified headers that were returned with the worker's response (they are now being removed: https://github.com/u32i64/readlogs/commit/7d0a1e830a65f92a3a4218af6cc84a6d97c65a5f).

    However, the cacheTtl for the fetch call is now set to 0 (https://github.com/u32i64/readlogs/commit/066dee8148ebd20713dce6756b967f180bd379ff), so this cache immediately expires (see Cloudflare cache responses; if the headers mentioned above aren't removed, the cf-cache-status given to the browser is EXPIRED), meaning the debug log should always be requested from the layer above.

  3. Cloudflare's caching of the worker's response:

    It's likely that this cache is not enabled.

    In any case, the worker sets the Cloudflare-CDN-Cache-Control header to no-store as an attempt to disable this cache, but because this header is not removed by Cloudflare, it seems that it is not used by Cloudflare (see CDN-Cache-Control).

  4. Caching in the user's browser:

    The response is explicitly cached here (currently, for 7 days) to avoid repeated requests in case the user is viewing the same debug log multiple times.

Building the app

  1. Install Yarn.

  2. Install CSS dependencies:

    yarn install
  3. Install Rust, for example via rustup.

  4. Install Trunk, for example via:

    cargo install trunk
  5. Build the app:

    trunk build

    Alternatively, serve it locally:

    trunk serve

    Note: Performance of debug builds may be significantly worse than that of release builds. For this reason, when using the app, it's recommended to build/serve in release mode instead:

    trunk build --release
    trunk serve --release
  6. The built app is now available in the dist folder.

Deploying the worker

  1. Follow steps 1–3 of the Cloudflare Workers Get started guide.
  2. Switch to the worker folder.
  3. Edit wrangler.toml if necessary (e.g. to change the name of the worker).
  4. Run the following command to publish your worker:
    wrangler publish
  5. The worker should now be published at <name>.<your-subdomain>.workers.dev.

Disclaimer

This is an unofficial project. It is not affiliated with the Signal Technology Foundation or Signal Messenger, LLC.

readlogs's People

Contributors

awaitlink avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

l3aalteshuva

readlogs's Issues

Less clunky file picker UI

It seems like it is useful to be able to access the file picker quickly, but it being at the very top feels clunky because it takes up a lot of vertical space. Maybe it should instead:

  • Be a simple <select> element;
  • Be accessible via some popup/popover.

Dark mode

Implement a "dark" appearance:

  • Match the system appearance via the @media-query;
  • Maybe also add an option: system/light/dark.

Fix compression description in readme

Signal Android/Desktop

The file is gzip-ped plain text. The worker alters the response to indicate this; presumably, Cloudflare then picks the best compression to deliver the response to your browser (e.g. brotli). The browser uncompresses the response and provides it to the app in plain text.

So all compression work is done by Cloudflare and the browser; neither the worker itself nor the app.

IIRC CF only tries compression for a fixed amount of time. If it takes to long or the file isn't smaller the compression is aborted.
As the logs are already highly compressed CF won't touch it. The compression might still apply to the headers but I'm not to sure about that.

Also judging from the CF support article there is a list of mime-types they compress and who'd guess application/gzip isn't one of them.

This can be confirmed when having a look at the request in the networks tab as no header like content-encoding | br is applied to it.

I suggest the point 2 being unified into roughly what the ios text says

Parse Android log level via `nom` first

Viewing logs with less horizontal scrolling

The problem itself may be slightly out of scope for this project, but still there are a few things that could make the experience better:

  • Show some kind of modal when pressing on a log entry (there, show details with no horizontal scrolling, only vertical).
  • Hide some columns as an option.
  • Wrap log lines in the table.
  • What else?

As a starting point, some of these features could just depend on the existing "Expand UI" / "Collapse UI" toggle.

Logcat: year

Due to Logcat entries not including the year, it's currently assumed to be the current year:

https://github.com/u32i64/readlogs/blob/c68e572907f4dd318088d3d72bcc82d4effc8f01/src/parsers/android.rs#L263

That's a problem in a few edge cases:

  • If the log spans multiple years (e.g. December 31 to January 1)—the year for each entry should be guessed separately;
  • If, for example, the log was taken on December 31 but viewed next year on January 1—perhaps it'd be better to get the year from the timestamp in the information section.

Maybe it's better to remove the year altogether, so that the app doesn't show wrong information. In that case, creating a date object should probably use a hardcoded year that includes February 29 (are there any other considerations that need to be made?), and after converting it to a string, remove the year.

Show available content even if parsing fails

If parsing fails:

  • Show the raw/plaintext file content in the Raw tab.
    • Consequently, remove the "input" from the error message linked below.
  • If it's due to the remainder not being empty, show at least what's been parsed successfully (with a notice that it's not complete).
    • Consequently, maybe remove the "output" from the error message linked below (although having access to the debug representation of it may be useful, maybe it should be shown in the Raw tab instead).
  • If some of the files (in case of Signal iOS) parsed successfully while others didn't, show at least those that parsed successfully. Indicate that other files could not be parsed (per-file errors).
    • Indicate in UI which files were parsed and which weren't.
    • If only some filenames couldn't be parsed, still show the files that parsed successfully.

https://github.com/u32i64/readlogs/blob/6267b116ed5f3f6a6349f5c3d514ba8908c8984e/src/parsers/mod.rs#L82-L88

(Edit: the error format has changed and the "input"/"output" values aren't currently shown in any case. However, it may be useful to show "output" in the case mentioned above.)

Compare two / multiple logs

It may be useful to allow viewing multiple debug logs at once, for example to:

  1. View logs from primary and linked devices side-by-side (with alignment by timestamps) to more easily understand the overall picture;
  2. Compare subsequently uploaded debug logs to see what the difference is (which log lines were added, which information changed).

Search: highlight matches

Highlight the text that matched the search string (e.g. so it's easier to see what caused a log entry to be included in the results).

Copy / download full raw file

Copying is technically already possible, but would require a very long manual selection. A button to copy / download the text would probably be better.

Ideally, this would not make any network requests, since the plain text is already available locally.

  • Copy
  • Download (implemented in d440da1)

Parse timestamps in information

Parse the timestamps that Signal Android and Signal Desktop logs provide in the Time key and show them like UTC log timestamps are shown.

"Find" latest remote config and startup logging

Signal iOS debug log files don't contain dedicated information sections, but it may be useful to automatically "find" the log lines about remote config, startup, etc. with the latest timestamps and show them in the information tab (perhaps, across all files, then indicating that the information tab does not change based on switching of files).

Use a prebuilt `trunk` binary in Cloudflare Pages

Something like 7f763c4 would significantly improve the speed of Cloudflare Pages builds, but it fails due to this:

./trunk: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by ./trunk)

(and hence that change was reverted for now in 360cee2).

Is there a way to make that binary work (for what it's worth, it does work in GitHub Actions), or would a special binary be needed for Cloudflare Pages' environment?


Edit: similar issue has been reported in:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.