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 LoggingTelegramLoggingTelegram 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 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 = .infoYou can change the default for all TelegramLogHandlers by changing the value of telegramLogDefaultLevel.
telegramLogDefaultLevel = .errorRemember, 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.
