Using in libraries
One of LogTape's key features is its ability to be used effectively both by library authors and application developers. This chapter will explore how LogTape can be integrated into libraries and how application developers can then work with and configure logging for those libraries.
For library authors
As a library author, you want to provide useful logging information without dictating how that information should be handled. LogTape allows you to do this seamlessly.
Best practices for library authors
Use namespaced categories: Start your log categories with your library name to avoid conflicts.
typescriptimport {
getLogger} from "@logtape/logtape"; constlogger=getLogger(["my-awesome-lib", "database"]);Don't
configure()
LogTape in your library: Leave configuration to the application developer.Use appropriate log levels: Use log levels judiciously. Reserve
"error"
for actual errors, use"info"
for important but normal operations, and"debug"
for detailed information useful during development.Provide context: Use structured logging to provide relevant context with each log message.
typescriptlogger.info("Database connection established", {host:dbHost,port:dbPort,username:dbUser});
Example: Logging in a library
Here's an example of how you might use LogTape in a library:
// my-awesome-lib/database.ts
import { getLogger } from "@logtape/logtape";
export class Database {
private logger = getLogger(["my-awesome-lib", "database"]);
constructor(
private host: string,
private port: number,
private user: string,
) {
}
connect() {
this.logger.info("Attempting to connect to database", {
host: this.host,
port: this.port,
user: this.user
});
// Simulating connection logic
if (Math.random() > 0.5) {
this.logger.error("Failed to connect to database", {
host: this.host,
port: this.port,
user: this.user
});
throw new Error("Connection failed");
}
this.logger.info("Successfully connected to database");
}
query(sql: string) {
this.logger.debug("Executing query", { sql });
// Query logic here
}
}
For application developers
As an application developer using a library that implements LogTape, you have full control over how logs from that library are handled.
Configuring Logs for a Library
Set up sinks: Decide where you want logs to go (console, file, etc.) and set up appropriate sinks.
Configure log levels: You can set different log levels for different parts of the library.
Add filters: You can add filters to fine-tune which log messages you want to see.
Example: Configuring logs for a library
Here's how you might configure logging for the example library we created above:
import { configure, getConsoleSink, getFileSink } from "@logtape/logtape";
import { Database } from "my-awesome-lib";
await configure({
sinks: {
console: getConsoleSink(),
file: getFileSink("app.log")
},
filters: {
excludeDebug: (record) => record.level !== "debug"
},
loggers: [
{
category: ["my-awesome-lib"],
level: "info",
sinks: ["console", "file"]
},
{
category: ["my-awesome-lib", "database"],
level: "debug",
sinks: ["file"],
filters: ["excludeDebug"]
}
]
});
const db = new Database("localhost", 5432, "user");
db.connect();
db.query("SELECT * FROM users");
In this configuration:
All logs from
"my-awesome-lib"
at"info"
level and above will go to bothconsole
andfile
.Database-specific logs at
"debug"
level and above will go to thefile
, but"debug"
level logs are filtered out.