Skip to content

Commit f2439f2

Browse files
docs: Improves documentation and error messages (#243)
Co-authored-by: andres <[email protected]>
1 parent 235a975 commit f2439f2

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

docs/en/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ Fast, Asynchronous, Concurrent R Application Deployment
1010

1111
## Overview
1212

13-
Welcome to faucet, your high-performance solution for deploying Plumber APIs and Shiny Applications with speed and efficiency. faucet is a Rust-based server that offers Round Robin and IP Hash load balancing, ensuring seamless scaling and distribution of your R applications. Whether you're a data scientist, developer, or DevOps enthusiast, faucet simplifies deployment, making it easy to manage replicas and balance loads effectively.
13+
Welcome to faucet, your high-performance solution for deploying Plumber APIs and Shiny Applications with speed and efficiency. faucet is a Rust-based server that offers Round Robin, IP Hash and Cookie Hash load balancing, ensuring seamless scaling and distribution of your R applications. Whether you're a data scientist, developer, or DevOps enthusiast, faucet simplifies deployment, making it easy to manage replicas and balance loads effectively.
1414

1515
## Features
1616

1717
- **High Performance:** faucet leverages Rust's speed for smooth and efficient execution of R applications.
18-
- **Load Balancing:** Choose Round Robin or IP Hash load balancing for optimal resource utilization.
18+
- **Load Balancing:** Choose Round Robin, IP Hash or Cookie Hash load balancing for optimal resource utilization.
1919
- **Replicas:** Scale Plumber APIs and Shiny Applications effortlessly with multiple replicas.
2020
- **Simplified Deployment:** faucet streamlines the deployment process for quick setup.
2121
- **Asynchronous & Concurrent:** Utilizes asynchronous and concurrent processing for resource efficiency and responsive request handling.
22+
- **Structured Event Tracing:** Gain deep insights into your Shiny applications with detailed, machine-readable logs stored directly in your database.
2223

2324

2425
## Installation

docs/en/logging.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,70 @@ Worker logs are divided into two components: `stdout` and `stderr`.
4646
level. The source is the worker who owns the underlying process. The message
4747
is the line of output from the process.
4848

49+
## Event Tracing
50+
51+
Beyond basic logging, faucet allows you to emit structured "events" from your R Shiny applications. These events provide rich, machine-readable data about what's happening within your application, making it easier to monitor, debug, and analyze its behavior.
52+
53+
### Emitting Events from R (Shiny)
54+
55+
To send structured events from your Shiny application, use the `faucet` R package. It provides a set of logging functions that wrap the core event emission logic:
56+
57+
- `faucet::info()`: For general informational events.
58+
- `faucet::warn()`: For non-critical issues or warnings.
59+
- `faucet::error()`: For significant errors that require attention.
60+
- `faucet::debug()`: For detailed debugging information (typically enabled during development).
61+
- `faucet::trace()`: For very fine-grained operational details (most verbose).
62+
63+
Each of these functions allows you to specify a `message`, an optional `body` for additional data, and a `parent` event to link related actions.
64+
65+
**1. Logging a simple informational message**
66+
67+
Use the `message` argument for a human-readable description of the event. You can also use `glue` syntax for dynamic messages.
68+
69+
```/dev/null/example.R#L1-1
70+
faucet::info("Application started successfully.")
71+
```
72+
73+
This would generate a structured log entry containing:
74+
- A unique `event_id` for this specific log.
75+
- `level: "Info"` indicating it's an informational message.
76+
- `message: "Application started successfully."`
77+
78+
**2. Including additional data with `body`**
79+
80+
The `body` argument accepts any R object that can be converted to JSON, such as a list. This is useful for attaching contextual data, diagnostics, or payload details to your events.
81+
82+
```/dev/null/example.R#L1-1
83+
faucet::info("User {user_id} logged in", user_id = "abc-123", body = list(session_duration_minutes = 15, ip_address = "192.168.1.10"))
84+
```
85+
86+
This event will capture:
87+
- The dynamic message: `"User abc-123 logged in"`.
88+
- A `body` containing a list with `session_duration_minutes` and `ip_address`, allowing you to store specific metrics or details alongside the log message.
89+
90+
**3. Tracing a sequence of operations with `parent`**
91+
92+
You can link related events by passing the `event_id` of a previous event as the `parent` argument. This creates a "parent-child" relationship, helping you trace the flow of complex operations through your application.
93+
94+
```/dev/null/example.R#L1-2
95+
event_id_start <- faucet::debug("Starting data retrieval from API.")
96+
# ... perform data retrieval ...
97+
faucet::info("Data retrieval complete.", parent = event_id_start, body = list(records_fetched = 1200))
98+
```
99+
100+
In this example:
101+
- The `debug` event marks the start of an operation, generating its own `event_id`.
102+
- The subsequent `info` event related to completion will include the `event_id_start` as its `parent_event_id`, clearly indicating that it's a follow-up to the data retrieval initiation.
103+
104+
### Storing and Analyzing Event Data
105+
106+
All structured events emitted by your Shiny applications are automatically captured by faucet and stored in the `faucet_log_events` table within your PostgreSQL database. This enables you to:
107+
108+
- **Query and Filter**: Easily search for specific events based on `level`, `message` content, or data within the `body`.
109+
- **Analyze Trends**: Track the frequency of certain events or errors over time.
110+
- **Reconstruct User Journeys**: Use `event_id` and `parent_event_id` to trace a user's interactions or the execution flow of a specific request through your application.
111+
- **Build Dashboards**: Use the structured data to create monitoring dashboards that provide real-time insights into your application's health and performance.
112+
49113
## Filtering logs
50114

51115
By default, faucet logs at the `INFO` level, which means that `ERROR`,

src/client/websockets.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ async fn server_upgraded_io(
277277
.send(Message::Close(Some(CloseFrame {
278278
code: CloseCode::Normal,
279279
reason: Utf8Bytes::from_static(
280-
"Connection purged due to inactivity or error.",
280+
"Connection purged due to inactivity, update or error.",
281281
),
282282
})))
283283
.await?;

src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl std::fmt::Display for FaucetError {
155155
Self::WSWriteBufferFull(buf) => write!(f, "Web Socket Write buffer full, {buf}"),
156156
Self::PostgreSQL(value) => write!(f, "PostgreSQL error: {value}"),
157157
Self::WebSocketConnectionInUse => write!(f, "WebSocket Connection in use"),
158-
Self::WebSocketConnectionPurged => write!(f, "WebSocket Connection purged"),
158+
Self::WebSocketConnectionPurged => write!(f, "WebSocket Connection purged. The client is trying to access a Shiny connection that does not exist."),
159159
Self::BadRequest(r) => match r {
160160
BadRequestReason::MissingQueryParam(param) => {
161161
write!(f, "Missing query parameter: {param}")

0 commit comments

Comments
 (0)