diff --git a/docs/content/concepts/assistant.md b/docs/content/concepts/assistant.md index 12b3dd369..9fb48d7bd 100644 --- a/docs/content/concepts/assistant.md +++ b/docs/content/concepts/assistant.md @@ -117,7 +117,7 @@ The following example uses the [OpenAI API client](https://platform.openai.com/d ```js ... - userMessage: async ({ client, message, say, setTitle, setStatus }) => { + userMessage: async ({ client, logger, message, say, setTitle, setStatus }) => { const { channel, thread_ts } = message; try { @@ -155,7 +155,7 @@ The following example uses the [OpenAI API client](https://platform.openai.com/d await say(llmResponse.choices[0].message.content); } catch (e) { - console.error(e); + logger.error(e); // Send message to advise user and clear processing status if a failure occurs await say('Sorry, something went wrong!'); diff --git a/docs/content/concepts/custom-routes.md b/docs/content/concepts/custom-routes.md index e776088e1..c52145266 100644 --- a/docs/content/concepts/custom-routes.md +++ b/docs/content/concepts/custom-routes.md @@ -44,7 +44,7 @@ const app = new App({ (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` @@ -73,7 +73,7 @@ app.event('message', async ({ event, client }) => { // Middleware methods execute on every web request receiver.router.use((req, res, next) => { - console.log(`Request time: ${Date.now()}`); + app.logger.info(`Request time: ${Date.now()}`); next(); }); @@ -85,6 +85,6 @@ receiver.router.post('/secret-page', (req, res) => { (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` \ No newline at end of file diff --git a/docs/content/concepts/deferring-initialization.md b/docs/content/concepts/deferring-initialization.md index fcc06a0c1..edd2e1e56 100644 --- a/docs/content/concepts/deferring-initialization.md +++ b/docs/content/concepts/deferring-initialization.md @@ -29,7 +29,7 @@ const app = new App({ // Now safe to call start() await app.start(process.env.PORT || 3000); } catch (e) { - console.log(e); + app.logger.error(e); process.exit(1); } })() diff --git a/docs/content/concepts/error-handling.md b/docs/content/concepts/error-handling.md index 653ebfbda..fa6e7072a 100644 --- a/docs/content/concepts/error-handling.md +++ b/docs/content/concepts/error-handling.md @@ -58,7 +58,7 @@ const app = new App({ // A more generic, global error handler app.error(async (error) => { // Check the details of the error to handle cases where you should retry sending a message or stop the app - console.error(error); + app.logger.error(error); }); ``` diff --git a/docs/content/concepts/logging.md b/docs/content/concepts/logging.md index 515eafd26..761663d6f 100644 --- a/docs/content/concepts/logging.md +++ b/docs/content/concepts/logging.md @@ -18,7 +18,36 @@ const app = new App({ }); ``` -## Sending log output somewhere besides the console +## Writing logs + +The logger included with the constructed `App` can be used to log writings throughout your application code: + +```javascript +(async () => { + app.logger.debug("Starting the app now!"); + await app.start(); + app.logger.info("⚡️ Bolt app started"); +})(); +``` + +Different app listeners can use the same `logger` that's provided as an argument to output additional details: + +```javascript +app.event("team_join", async ({ client, event, logger }) => { + logger.info("Someone new just joined the team."); + try { + const result = await client.chat.postMessage({ + channel: "C0123456789", + text: `Welcome to the team, <@${event.user.id}>!`, + }); + logger.debug(result); + } catch (error) { + logger.error(error); + } +}); +``` + +## Redirecting outputs If you want to send logs to somewhere besides the console or want more control over the logger, you can implement a custom logger. A custom logger must implement specific methods (known as the `Logger` interface): diff --git a/docs/content/concepts/receiver.md b/docs/content/concepts/receiver.md index ba99d8ad2..361f2be43 100644 --- a/docs/content/concepts/receiver.md +++ b/docs/content/concepts/receiver.md @@ -58,7 +58,7 @@ app.use(async ({ logger, context, next }) => { // Start your app await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` diff --git a/docs/content/concepts/socket-mode.md b/docs/content/concepts/socket-mode.md index a020723a9..55f34e9fc 100644 --- a/docs/content/concepts/socket-mode.md +++ b/docs/content/concepts/socket-mode.md @@ -19,7 +19,7 @@ const app = new App({ (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` @@ -48,6 +48,6 @@ const app = new App({ (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` \ No newline at end of file diff --git a/docs/content/getting-started.mdx b/docs/content/getting-started.mdx index 426390309..fcdfad899 100644 --- a/docs/content/getting-started.mdx +++ b/docs/content/getting-started.mdx @@ -110,7 +110,7 @@ const app = new App({ // Start your app await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -238,7 +238,7 @@ app.message('hello', async ({ message, say }) => { // Start your app await app.start(); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -263,7 +263,7 @@ app.message('hello', async ({ message, say }) => { // Start your app await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -350,7 +350,7 @@ app.message('hello', async ({ message, say }) => { // Start your app await app.start(); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -394,7 +394,7 @@ app.message('hello', async ({ message, say }) => { // Start your app await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -468,7 +468,7 @@ app.action('button_click', async ({ body, ack, say }) => { // Start your app await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` diff --git a/docs/content/reference.md b/docs/content/reference.md index e9cca7635..92c11ccbe 100644 --- a/docs/content/reference.md +++ b/docs/content/reference.md @@ -48,6 +48,7 @@ Listener functions have access to a set of arguments that may change based on th | `respond` | `action`, `shortcut`, `view`, `command` | Function that responds to an incoming event **if** it contains a `response_url`. `respond` returns a promise that resolves with the results of responding using the `response_url`. For shortcuts, `respond` will **only** work for message shortcuts (not global shortcuts). For views, `respond` will **only** work when using `response_url_enabled: true` for [conversations list](https://api.slack.com/reference/block-kit/block-elements#conversation_select) and [channels list](https://api.slack.com/reference/block-kit/block-elements#channel_select) select menus in input blocks in modals. | | `context` | All listeners | Event context. This object contains data about the event and the app, such as the `botId`. Middleware can add additional context before the event is passed to listeners. | | `body` | All listeners | Object that contains the entire body of the request (superset of `payload`). Some accessory data is only available outside of the payload (such as `trigger_id` and `authorizations`). | +| `logger` | All listeners | The application logger with all of [the logging functions](/concepts/logging) for output. | #### Body and payload references The structure of the `payload` and `body` is detailed on the API site: diff --git a/docs/content/tutorials/ai-assistant.md b/docs/content/tutorials/ai-assistant.md index 58c8d9dae..a7c5dcfe9 100644 --- a/docs/content/tutorials/ai-assistant.md +++ b/docs/content/tutorials/ai-assistant.md @@ -137,7 +137,7 @@ In this sample app, we've opted to rely on the thread context information provid The [`assistant_thread_started`](https://api.slack.com/events/assistant_thread_started) event is sent when a user opens the assistant container, either with a DM or from the top nav bar entry point. Responding to this event starts the conversation with the user. Here we will greet the user then set some suggested prompts. The `message` field of each prompt is what is sent to the assistant when the user clicks on the prompt. ```js - threadStarted: async ({ event, say, setSuggestedPrompts, saveThreadContext }) => { + threadStarted: async ({ event, logger, say, setSuggestedPrompts, saveThreadContext }) => { const { context } = event.assistant_thread; try { @@ -176,7 +176,7 @@ The [`assistant_thread_started`](https://api.slack.com/events/assistant_thread_s */ await setSuggestedPrompts({ prompts, title: 'Here are some suggested options:' }); } catch (e) { - console.error(e); + logger.error(e); } }, ``` @@ -196,12 +196,12 @@ The [`assistant_thread_context_changed`](https://api.slack.com/events/assistant_ * method (either the DefaultAssistantContextStore or custom, if provided). * https://api.slack.com/events/assistant_thread_context_changed */ - threadContextChanged: async ({ saveThreadContext }) => { + threadContextChanged: async ({ logger, saveThreadContext }) => { // const { channel_id, thread_ts, context: assistantContext } = event.assistant_thread; try { await saveThreadContext(); } catch (e) { - console.error(e); + logger.error(e); } }, ``` @@ -272,7 +272,7 @@ For this scenario, the user is in a channel and the app has access to that chann limit: 50, }); } else { - console.error(e); + logger.error(e); } } ``` @@ -359,7 +359,7 @@ After getting the thread replies, we map them to the appropriate object structur // Provide a response to the user await say({ text: llmResponse.choices[0].message.content }); } catch (e) { - console.error(e); + logger.error(e); // Send message to advise user and clear processing status if a failure occurs await say({ text: 'Sorry, something went wrong!' }); diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-routes.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-routes.md index d42fb0420..61b168b96 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-routes.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/custom-routes.md @@ -44,7 +44,7 @@ const app = new App({ (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` @@ -71,7 +71,7 @@ app.event('message', async ({ event, client }) => { }); receiver.router.use((req, res, next) => { - console.log(`Request time: ${Date.now()}`); + app.logger.info(`Request time: ${Date.now()}`); next(); }); @@ -83,6 +83,6 @@ receiver.router.post('/secret-page', (req, res) => { (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` \ No newline at end of file diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/deferring-initialization.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/deferring-initialization.md index 4c4c7e397..b3cca2bd4 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/deferring-initialization.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/deferring-initialization.md @@ -25,7 +25,7 @@ const app = new App({ // init() メソッドを呼び出したので、`start()` メソッドを安全に呼び出すことができる await app.start(process.env.PORT || 3000); } catch (e) { - console.log(e); + app.logger.error(e); process.exit(1); } })() diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md index 5d5159c4e..052808495 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/error-handling.md @@ -50,7 +50,7 @@ const app = new App({ // より一般的なグローバルのエラーハンドラー app.error(async (error) => { // メッセージ送信をリトライすべきか、アプリを停止すべきか判断するためにエラーの詳細を確認 - console.error(error); + app.logger.error(error); }); ``` diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/socket-mode.md b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/socket-mode.md index b765a8e5b..607771278 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/socket-mode.md +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/concepts/socket-mode.md @@ -19,7 +19,7 @@ const app = new App({ (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` @@ -48,6 +48,6 @@ const app = new App({ (async () => { await app.start(); - console.log('⚡️ Bolt app started'); + app.logger.info('⚡️ Bolt app started'); })(); ``` \ No newline at end of file diff --git a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx index 0e493f05c..b3663939c 100644 --- a/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx +++ b/docs/i18n/ja-jp/docusaurus-plugin-content-docs/current/getting-started.mdx @@ -112,7 +112,7 @@ const app = new App({ // アプリを起動します await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -250,7 +250,7 @@ app.message('hello', async ({ message, say }) => { // アプリを起動します await app.start(); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -275,7 +275,7 @@ app.message('hello', async ({ message, say }) => { // アプリを起動します await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -366,7 +366,7 @@ app.message('hello', async ({ message, say }) => { // アプリを起動します await app.start(); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -410,7 +410,7 @@ app.message('hello', async ({ message, say }) => { // アプリを起動します await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -482,7 +482,7 @@ app.action('button_click', async ({ body, ack, say }) => { // アプリを起動します await app.start(); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` @@ -533,7 +533,7 @@ app.action('button_click', async ({ body, ack, say }) => { // アプリを起動します await app.start(process.env.PORT || 3000); - console.log('⚡️ Bolt app is running!'); + app.logger.info('⚡️ Bolt app is running!'); })(); ``` diff --git a/src/App.ts b/src/App.ts index e937eefe1..793d30dec 100644 --- a/src/App.ts +++ b/src/App.ts @@ -222,7 +222,7 @@ export default class App private receiver: Receiver; /** Logger */ - private logger: Logger; + public logger: Logger; /** Log Level */ private logLevel: LogLevel;