LWC
In this article we'll take a look at logging in LWC components and familiarize ourselves with Triton's JS interface.
LWC is a powerful UI framework in use today by organizations of all sizes. LWC provides a wealth of capabilities that extend the platform's user interface and allow developers to create rich visual experiences. However, with great power comes complexity.
It's quite common for LWC-based interfaces to become large and complex. At that point, one needs a little something to help manage the expanding functionality without loosing sanity. As you may have guessed, this is yet another area to leverage Pharos Triton. Let's first examine the basics.
Creating an LWC Logger
The good news is that getting a hold of the Triton logger in LWC is quite easy. The logger component is called triton. To access its capabilities, simply include it in your controller class. The initialization timing depends on whether your component uses @wire methods:
Components Without @wire
For components without @wire decorators, initialize Triton in the connectedCallback() method. This is safe because connectedCallback is one of the first lifecycle hooks that fires when a component is added to the DOM, and without @wire decorators, there's no risk of missing early data or error events:
Components With @wire
When using @wire decorators, we need to be more careful about initialization timing. The Lightning Web Component lifecycle follows this sequence:
Constructor runs
@wire decorators are initialized and begin fetching data
connectedCallback executes
Component renders
This means that if we initialize Triton in connectedCallback, we might miss important wire-related events that occur between steps 2 and 3. Therefore, for components with @wire decorators, we initialize in the constructor.
Best Practice: While we've shown both initialization patterns, it's actually perfectly safe and arguably cleaner to always initialize Triton in the constructor, regardless of whether your component uses @wire or not. The constructor initialization will work in all scenarios because:
It ensures the logger is available as early as possible in the component lifecycle
Triton uses the singleton pattern, so there's no performance penalty
It reduces cognitive overhead - you don't need to think about where to initialize based on @wire usage
It future-proofs your component if you later add @wire decorators
The only minor consideration is that if your component is never actually connected to the DOM (very rare), you'll have initialized Triton unnecessarily. However, this edge case rarely outweighs the benefits of consistent initialization.
Inside Triton.js
The LWC version of Triton implements a robust logging system with transaction management and automatic log flushing. The logger provides different logging levels (error, warning, info, debug) and uses a builder pattern for constructing logs with rich context.
Each log can include details such as:
Transaction ID for tracking related logs
User ID and timestamp
Component stack traces
Runtime information (browser, device, performance metrics)
Summary and detailed information
The logger automatically manages log buffering and flushing to the server, with an auto-flush mechanism that triggers after a period of inactivity.
TritonBuilder Pattern
Triton uses a builder pattern that allows for fluent, chainable logging statements. Each logging method (error, warning, info, debug) returns a builder instance that you can use to add additional context to your log:
The builder captures rich contextual information automatically, including component details, runtime information, and transaction IDs. You can also set up template builders for consistent logging patterns across your component:
Buffered vs Immediate Logging
Triton provides two methods for sending logs to the server:
log()
: Buffers the log entry for later sending. Multiple logs will be sent together during periodic flush operations or when explicitly flushed. This is more efficient for high-volume logging.logNow()
: Immediately sends the log entry to the server. This is useful for critical errors or when immediate logging feedback is required. Returns a Promise that resolves when the log is saved.
When using logNow()
, only the specific log entry passed to the method is sent to the server immediately. Any other logs in the buffer remain there until the next flush operation. This selective immediate logging is particularly useful when you need to ensure critical logs are saved without affecting the buffering of less urgent logs.
For example:
Real-World Logging Scenario
Consider a complex account management interface where users can perform multiple operations:
In this scenario:
Debug and success logs are buffered because they're routine and non-critical
Error logs are sent immediately because:
They need to be available right away for troubleshooting
The error might prevent subsequent operations from completing
Support teams can respond in real-time to mission-critical failures
The error context is preserved even if the component crashes
Time-sensitive operations can trigger immediate support intervention
This immediate logging pattern is particularly valuable in scenarios like financial transactions, healthcare operations, or other mission-critical processes where real-time monitoring and rapid response are essential.
Advanced Wire Patterns with Logging
When working with wired properties in LWC, there's a powerful pattern that combines programmatic refresh capabilities with logging. This involves wiring the same Apex method to two different properties:
This pattern serves two important purposes:
Programmatic Refresh: The
wiredOrderItems
property provides a reference that can be used to programmatically refresh the data usingrefreshApex(this.wiredOrderItems)
.Automatic Logging: The second wire decorator with the callback function handles data processing and automatically logs both successful retrievals and errors.
This approach is particularly useful when you need to:
Track all data loading attempts, both automatic and manual refreshes
Maintain a detailed audit trail of data operations
Debug intermittent loading issues
Monitor performance patterns in data retrieval
The dual-wire pattern doesn't cause double network requests - LWC's wire service is smart enough to share a single subscription for identical wire configurations.
Now that we've covered some basics, let's have a look at a more interesting example and combine the LWC logger with its Apex counterpart.
Last updated