Add Hive Logger JSON writer to benchmarks - #54
Conversation
There was a problem hiding this comment.
Summary of Changes
Hello @enisdenjo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces a new benchmark to measure the performance of the Hive Logger's JSON writer. The primary goal is to expand our benchmarking suite to include this specific logging solution and ensure its performance characteristics are understood in comparison to existing benchmarks.
Highlights
- New Benchmark Addition: I've added a new benchmark specifically for the
@graphql-hive/loggerlibrary, focusing on the performance of itsJSONLogWriterwhen logging messages with object payloads. - Fair Benchmarking Practices: To ensure a fair comparison with other loggers that write to
devNull, I've included a temporary override ofconsole.logwithin the Hive Logger benchmark. This prevents console output from skewing performance results.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request introduces a benchmark for the @graphql-hive/logger's JSONLogWriter into the existing JSON benchmark suite. The implementation cleverly overrides the global console.log function to a no-op to ensure that the benchmark measures JSON serialization performance without including console I/O overhead, thereby maintaining fairness with other loggers benchmarked against /dev/null.
My review includes two main suggestions, both rated as medium severity:
- Enhance Robustness of
console.logRestoration: I've recommended wrapping the benchmark logic that modifies and usesconsole.logwithin atry...finallyblock. This ensures that the originalconsole.logfunction is restored even if an error occurs during the benchmark's setup or execution phase, preventing potential interference with subsequent tests or operations. - Explore Cleaner Alternatives to Global Modification: I've suggested investigating whether
JSONLogWritercould be directly configured with a null output stream or a no-op writer. If the library supports this, it would be a cleaner and less invasive approach than modifying the globalconsole.logobject, adhering to best practices of minimizing global state changes.
These suggestions aim to improve the robustness and maintainability of the new benchmark code. As noted in the pull request description, the benchmark results in benchmarks/README.md will need to be updated to include Hive Logger in the JSON benchmark section once the results are generated on a consistent environment.
| const consoleLog = console.log; | ||
| console.log = () => {}; | ||
|
|
||
| const logger = new hiveLogger.Logger({ writers: [new hiveLogger.JSONLogWriter()] }); | ||
| yield () => logger.info("Test log message: %o", { foo: 1, bar: 2 }); | ||
|
|
||
| console.log = consoleLog; |
There was a problem hiding this comment.
Modifying global objects like console.log can introduce risks. If an error occurs after console.log is replaced (e.g., during logger initialization on line 61) but before it's restored on line 64, console.log could remain in a no-op state, potentially affecting subsequent operations or other tests in the suite.
Using a try...finally block will ensure that console.log is reliably restored to its original state, even if errors occur within the try block. This enhances the robustness of the benchmark setup.
This suggestion aligns with general best practices for writing robust JavaScript/TypeScript code, especially when dealing with modifications to global state.
const originalConsoleLog = console.log;
console.log = () => {}; // No-op
try {
const logger = new hiveLogger.Logger({ writers: [new hiveLogger.JSONLogWriter()] });
yield () => logger.info("Test log message: %o", { foo: 1, bar: 2 });
} finally {
console.log = originalConsoleLog; // Ensure restoration
}There was a problem hiding this comment.
try/catch is expensive and can scew the benchmark results.
| // noop to avoid console output during the benchmark, making it fair since other loggers write to devNull | ||
| const consoleLog = console.log; | ||
| console.log = () => {}; |
There was a problem hiding this comment.
The current approach of temporarily replacing the global console.log (as explained in the comment on line 57) achieves the goal of benchmarking JSON serialization without the overhead of console I/O. This makes the benchmark comparable to others that write to /dev/null.
However, modifying global state is generally best avoided if a more direct, less invasive method is available. It would be worth investigating if hiveLogger.JSONLogWriter offers a way to be configured with a custom output stream or a no-op write function. For example:
// Hypothetical example based on patterns seen elsewhere (e.g., NullLogWriter in null.ts)
import { Writable } from 'node:stream';
// A stream that does nothing
const nullStream = new Writable({
write(chunk, encoding, callback) {
callback();
}
});
const logger = new hiveLogger.Logger({
// Assuming JSONLogWriter could take a stream option
writers: [new hiveLogger.JSONLogWriter({ stream: nullStream })]
});If JSONLogWriter is inherently tied to the global console.log and lacks such configuration options, the current monkey-patching approach is a pragmatic workaround. Exploring a direct configuration, if possible, would lead to a cleaner and potentially safer benchmark setup, aligning with principles of minimizing side effects.
I didn't update the results since we're running on different machines. How would you like me to proceed?