Welcome to LoggingTelegram – a logging backend for SwiftLog that sends log messages by a Telegram Bot.
Inspired by and forked from LoggingSlack.
LoggingTelegram requires Xcode 11 or a Swift 5.2 toolchain with the Swift Package Manager.
Add the LoggingTelegram package as a dependency to your Package.swift
file.
.package(url: "https://github.com/stevapple/swift-log-telegram.git", from: "0.0.1")
Add LoggingTelegram to your target's dependencies.
.target(name: "Example", dependencies: ["LoggingTelegram"])
Then start using by:
import LoggingTelegram
LoggingTelegram uses Telegram Bot API to send log messages to any Telegram chat.
You can chat with BotFather to create a new bot and get its API token. The config methods are described here.
You need to pass the token to TelegramLogHandler.init
to set it up.
You can access a chat by its ID. There are various ways to get the ID of a chat, some are discussed in this thread.
You can create a group chat with TelegramGroup.id(_:Int)
, a channel with TelegramChannel.id(_:Int)
and a user chat with TelegramUser.id(_:Int)
.
Alternatively, you can create a channel by its name: TelegramChannel.name(_:String)
, remember to drop @
prefix.
LoggingTelegram is intended to be used as a secondary logging backend to send urgent log messages directly to Telegram.
You can use SwiftLog's MultiplexLogHandler
to setup LoggingTelegram with another logging backend.
import Logging
import LoggingTelegram
let channel = TelegramChannel.name("test").mentioning([1, 3]).mentioning("2")
LoggingSystem.bootstrap { label in
MultiplexLogHandler([
// Setup TelegramLogHandler with your API Token and Chat instance
TelegramLogHandler(label: label, token: "Your Bot Token Here", chat: channel),
// Setup the standard logging backend to enable console logging
StreamLogHandler.standardOutput(label: label),
// Setup multiple TelegramLogHandlers
// TelegramLogHandler(label: label, token: "Your (Another) Bot Token Here", chat: TelegramGroup.id(123))
])
}
Since SwiftLog does not support parallel logs and that network connection takes time, loggers after the TelegramLogHandler
may need to wait for its HTTP request sometimes.
If you want to get the precise timestamp at the console, you may put TelegramLogHandler
after StreamLogHandler
:
import Logging
import LoggingTelegram
let channel = TelegramChannel.name("test").mentioning([1, 3]).mentioning("2")
LoggingSystem.bootstrap { label in
MultiplexLogHandler([
StreamLogHandler.standardOutput(label: label),
TelegramLogHandler(label: label, token: "Your Bot Token Here", chat: channel),
TelegramLogHandler(label: label, token: "Your (Another) Bot Token Here", chat: TelegramGroup.id(123))
])
}
You can now use SwiftLog as usual and critical log messages are sent directly to Telegram. Test code as below.
import Logging
let logger = Logger(label: "com.example.ExampleApp.main")
logger.critical("Oops, something went wrong!")
The logger will send a Telegram message as a bot (if the level matches) and a console message since both logging backends were setup. The example above gives the following outputs:
2020-04-07T16:05:25+0800 critical: Oops, something went wrong!
Only messages of log level critical
are sent to Telegram by default.
You can adjust the minimal log level for a specific TelegramLogHandler
by setting its logLevel
property, or initializing with a level
property.
var handler = TelegramLogHandler(label: "test", token: "Your Bot Token Here", chat: TelegramGroup.id(123), level: .error)
// Unrecommended! Low log levels may burden the server and abuse the Telegram function
handler.logLevel = .info
You can change the default for all TelegramLogHandler
s by changing the value of telegramLogDefaultLevel
.
telegramLogDefaultLevel = .error
Remember, the TelegramLogHandler.logLevel
property has a priority to telegramLogDefaultLevel
.
You can mention someone in a group chat or a channel, simply by the various .mentioning()
APIs, listed below:
import LoggingTelegram
var chat = TelegramChannel.name("test")
// By TelegramUser
let users = [1,2].map { TelegramUser.id($0) }
chat = chat.mentioning(users) // Returns a new TelegramChannel instance
// You can use his username to mention a user
let user = TelegramUser.name("testme")
chat = chat.mentioning(user)
// By TelegramRawId (A more flexible alias of the "TelegramUser" version)
chat = chat.mentioning(.id(3))
chat = chat.mentioning([.name("newtest"), .id(4)])
// By User ID
chat = chat.mentioning(5)
chat = chat.mentioning([6,7,8])
// By Username
chat = chat.mentioning("test 1")
chat = chat.mentioning(["test 2", "test 3"])
In brief, the chaining style is recommended when creating a chat:
import LoggingTelegram
TelegramChannel.name("test").mentioning([.id(1), .name("2"), .id(3)])
// or
TelegramChannel.name("test").mentioning([1, 3]).mentioning("2")
To not disturb subscribers, you may need to mute the message. You can pass a mute: Bool
to the initializer to make it silent:
TelegramLogHandler(label: label, token: "Your Bot Token Here", chat: channel, mute: true)
The mentioned users won't be muted.
You should know what you're doing though this package. Do not use it at client-side to protect the subscribers' info and your Bot Token.