{"id":13794827,"url":"https://github.com/aparajita/capacitor-logger","last_synced_at":"2026-01-17T11:54:30.743Z","repository":{"id":46537761,"uuid":"295511379","full_name":"aparajita/capacitor-logger","owner":"aparajita","description":"Better logging for the web and native Ionic/Capacitor apps","archived":false,"fork":false,"pushed_at":"2024-04-22T17:11:04.000Z","size":1060,"stargazers_count":18,"open_issues_count":6,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-11T11:44:43.069Z","etag":null,"topics":["capacitor","capacitor-android","capacitor-ios","capacitor-plugin","capacitor-web"],"latest_commit_sha":null,"homepage":"","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aparajita.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-14T18:59:51.000Z","updated_at":"2025-06-02T18:12:40.000Z","dependencies_parsed_at":"2024-01-02T23:10:10.069Z","dependency_job_id":"0dd4d2c7-e474-42f9-bcbd-b867a31973e2","html_url":"https://github.com/aparajita/capacitor-logger","commit_stats":{"total_commits":34,"total_committers":1,"mean_commits":34.0,"dds":0.0,"last_synced_commit":"d605d0f7de5f850967caab0b71a3305ed1c3dc8f"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/aparajita/capacitor-logger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aparajita%2Fcapacitor-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aparajita%2Fcapacitor-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aparajita%2Fcapacitor-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aparajita%2Fcapacitor-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aparajita","download_url":"https://codeload.github.com/aparajita/capacitor-logger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aparajita%2Fcapacitor-logger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28508462,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T11:50:55.898Z","status":"ssl_error","status_checked_at":"2026-01-17T11:50:55.569Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["capacitor","capacitor-android","capacitor-ios","capacitor-plugin","capacitor-web"],"created_at":"2024-08-03T23:00:48.575Z","updated_at":"2026-01-17T11:54:30.718Z","avatar_url":"https://github.com/aparajita.png","language":"CSS","funding_links":[],"categories":["Plugins","Aparajita plugins"],"sub_categories":["Community Plugins","Specialized Hardware"],"readme":"\u003cdiv class=\"markdown-body\"\u003e\n\n# capacitor-logger\u0026nbsp;\u0026nbsp;[![npm version](https://badge.fury.io/js/@aparajita%2Fcapacitor-logger.svg)](https://badge.fury.io/js/@aparajita%2Fcapacitor-logger)\n\nThis [Capacitor 6](https://capacitorjs.com) plugin is an almost complete implementation of the [`Console`](https://developer.mozilla.org/en-US/docs/Web/API/Console) interface for web, iOS and Android.\n\nA [demo](https://github.com/aparajita/capacitor-logger-demo) is available that illustrates the usage of the API.\n\n[Installation](#installation) | [Configuration](#configuration) | [Usage](#usage) | [API](#api)\n\n## Features\n\n- Does not attempt to monkey patch the `Console` interface, uses a separate `Logger` class.\n- Set a [log level](#log-levels) — including `silent` — for the logger.\n- Completely filter out logs based on the log level.\n- Logs are **not** part of Capacitor’s output, you get your own distinct tag.\n- Customize the log labels, including using emoji. 😁\n- Send logs to the system log on iOS, so you can view a production app’s logs on any device using `Console.app`. 🎉\n- Instantiate multiple loggers.\n- `Logger` class is available for use by native plugins and apps! 🚀\n\n### Log levels\n\n`Logger` uses the same log levels as `Console`, from lowest to highest: `error`, `warn`, `info`, and `debug`. In addition, `silent` is used to disable all logging. These are all defined in the [`LogLevel`](#loglevel) enum.\n\nUnlike `Console`, each instance of `Logger` has its own log level which determines what is logged. You can change the level at any time by setting the `.level` property to a `LogLevel` or a level name. If the level name is invalid, it is ignored.\n\nFor any given log message, there is a log level associated. If the logger’s current log level is less than the log message’s level, the message is ignored. For example, if the current log level is `info` and a `debug` message is logged, it will be ignored, because `info` is a lower level than `debug`.\n\n\u003e **Note:** It is a known bug that iOS simulators will not log debug messages to the system log.\n\n### Distinct (and distinctive!) log output\n\nIf you use `console` methods, your logs go through Capacitor and don’t exactly stand out. Hey Capacitor, my app can stand on its own! 😁 With `Logger`, you can configure a custom label for each level as well as a tag that identifies the source of the log message.\n\n#### Level labels\n\nThere are two styles of level labels: emoji and text. The style determines how the label is displayed. By default, the label is displayed as an emoji. The default (boring) labels are:\n\n```\nerror: '🔴',\nwarn: '🟠',\ninfo: '🟢',\ndebug: '🔎',\n```\n\nYou can set the labels to whatever you want using the `.labels` property. For example, you could use something with a little more character:\n\n```\nerror: '☠️',\nwarn: '👀',\ninfo: '💬',\ndebug: '🪰',\n```\n\nHere is a sample of what emoji and text labels look like in a browser console:\n\n\u003cimg src=\"docs/web-labels.png\" width=\"400\" /\u003e\n\nAnd in the Xcode console:\n\n\u003cimg src=\"docs/xcode-labels.png\" width=\"400\" /\u003e\n\nAnd in macOS `Console.app` 🎉:\n\n![](./docs/console-labels.png)\n\nAnd in Android logcat:\n\n\u003cimg src=\"docs/logcat-labels.png\" width=\"400\" /\u003e\n\nNote that on Android, if the first character of a label is ASCII, the label is automatically surrounded by square brackets.\n\n## Installation\n\nThe `Logger` class provided by this plugin is implemented in TypeScript (web), Swift (iOS) and Java (Android), and is exported for use within your own native code.\n\nIn your plugin or app project:\n\n```shell\npnpm add @aparajita/capacitor-logger\n```\n\nIf you only plan to use the logger from TypeScript code (even on native platforms), this is all you need to do.\n\nOne of the original motivations for this plugin was to have better logging from my other plugins. If you are a plugin author, or writing native code at the app layer, you can use a native `Logger` class in your native code. To use the logger in your plugins, you must add it both to the plugin **_and_** to any app that uses your plugin, because the dependency is not transitive.\n\nIf you are want to use `Logger` in your plugins, there are a few more installation steps to take. In the following examples we will assume your plugin is called `MyPlugin`.\n\n### iOS\n\n1. Add a reference to this plugin in `MyPlugin.podspec`.\n\n```podspec\nPod::Spec.new do |s|\n  # ...standard stuff\n  s.dependency 'Capacitor'\n\n  # 👇 Add this\n  s.dependency 'AparajitaCapacitorLogger'\n\n  s.swift_version = '5.1'\nend\n```\n\n2. Add a reference to this plugin in `ios/Podfile`.\n\n```podfile\n# 👇 Add this\ndef my_pods\n  pod 'AparajitaCapacitorLogger', :path =\u003e '../node_modules/@aparajita/capacitor-logger'\nend\n\ntarget 'Plugin' do\n  capacitor_pods\n\n  # 👇 Add this\n  my_pods\nend\n\ntarget 'PluginTests' do\n  capacitor_pods\n\n  # 👇 Add this\n  my_pods\nend\n```\n\nAdd this plugin as a peer dependency in your plugin’s `package.json`.\n\n```json\n{\n  \"peerDependencies\": {\n    \"@aparajita/capacitor-logger\": \"^4.0.0\"\n  }\n}\n```\n\n### Android\n\n1. Add a reference to this plugin in your plugin’s `settings.gradle (android)`.\n\n```gradle\ninclude ':aparajita-capacitor-logger'\nproject(':aparajita-capacitor-logger').projectDir = new File('../node_modules/@aparajita/capacitor-logger')\n```\n\n2. Add a reference to this plugin in your plugin’s `build.gradle (android)`.\n\n```gradle\ndependencies {\n  implementation ':aparajita-capacitor-logger'\n}\n```\n\n## Usage\n\nThe `Logger` API is similar across web, Swift and Java. In Swift I have used as many idiomatic features of the language as possible to make coding easier (yeah Java, I’m looking at you).\n\n### TypeScript\n\nTo use the logger in TypeScript , import it into your project:\n\n```typescript\nimport { Logger } from '@aparajita/capacitor-logger'\n```\n\nThen create a logger instance:\n\n```typescript\n// You can also pass the level and labels here if you want.\nconst logger = new Logger('MyApp')\n```\n\nIf you are only using a single logger for the entire app, you will probably want to put this code in a separate file:\n\n```typescript\n// logger.ts\nimport { Logger } from '@aparajita/capacitor-logger'\n\nconst logger = new Logger('MyApp')\nexport default logger\n```\n\nThen import the logger into your code:\n\n```typescript\nimport logger from '@/logger'\n\nlogger.info('Hello world!')\n```\n\n### Swift\n\nIn your plugin or app’s Swift code where you want to instantiate the logger, import the logger module:\n\n```swift\nimport AparajitaCapacitorLogger\n```\n\nIf you want to use a hard-coded log tag, create a logger instance anywhere you want:\n\n```swift\nlet logger = Logger(withTag: \"MyPlugin\")\n```\n\nIf you are writing a plugin and want to use your plugin’s name as the log tag, you have to split up the declaration and instantiation into two lines, because the plugin is not fully constructed until `load()`:\n\n```swift\n@objc(SplashScreen)\npublic class SplashScreen: CAPPlugin {\n  var logger: Logger?\n\n  override public func load() {\n    logger = Logger(withPlugin: self)\n  }\n```\n\nThen use the logger anywhere you want:\n\n```swift\n// If you intantiated directly\nlogger.info(\"Hello world!\")\n\n// If you used an optional\nlogger?.info(\"Hello world!\")\n```\n\nIf you want to use a logger in the application layer and use the application’s display name as its tag, there is a convenience initializer you can use. First declare the logger in your `AppDelegate`.\n\n```swift\nimport UIKit\nimport AparajitaCapacitorLogger\nimport Capacitor\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n  var logger: Logger?\n```\n\nIf you don’t care about using the Capacitor config file, you can initialize the logger in `application(_:didFinishLaunchingWithOptions)`.\n\n```swift\nfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -\u003e Bool {\n  // Override point for customization after application launch.\n  logger = Logger(withAppDelegate: self)\n  logger?.info(\"ready to roll!\")\n  return true\n}\n```\n\nIf you want the Capacitor config file to be used, you have to initialize the logger the first time `applicationDidBecomeActive` is called, because config is not available before then.\n\n```swift\nfunc applicationDidBecomeActive(_ application: UIApplication) {\n  // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n\n  if logger == nil {\n    logger = Logger(withAppDelegate: self)\n    logger?.info(\"ready to roll!\")\n  }\n}\n```\n\n### Android\n\nImport the `logger` module in your plugin’s code:\n\n```java\nimport com.aparajita.capacitor.logger.*;\n\n```\n\nIf you want to use a hard-coded log tag, create a logger instance anywhere you want:\n\n```java\nLogger logger = new Logger(\"MyPlugin\");\n```\n\nIf you are writing a plugin and want to use your plugin’s name as the log tag, you have to split up the declaration and instantiation into two lines, because the plugin is not fully constructed until `load()`:\n\n```java\n@CapacitorPlugin(name = \"MyPlugin\")\npublic class MyPluin extends Plugin {\n\n  private Logger logger;\n\n  @Override\n  public void load() {\n    logger = new Logger(this);\n  }\n}\n\n```\n\nThen use the logger anywhere you want:\n\n```java\nlogger.info(\"Hello world!\")\n```\n\nIf you want to use a logger in the application layer and use the application’s display name as its tag, there is a convenience constructor you can use. First declare the logger in your `MainActivity`.\n\n```swift\nimport com.aparajita.capacitor.logger.*;\n\npublic class MainActivity extends BridgeActivity {\n  private Logger logger;\n```\n\nThen construct the logger in `load()`. This constructor will fetch the tag from the app’s display name and also read the Capacitor config.\n\n```swift\n@Override\nprotected void load() {\n  super.load();\n  logger = new Logger(this);\n}\n```\n\n## Configuration\n\nLoggers can be configured at runtime through various class methods. For loggers created _within native code_, you can also configure the initial state by setting values in the Capacitor config file of any app that installs this plugin. The configuration schema is as follows:\n\n```typescript\nconst config: CapacitorConfig = {\n  plugins: {\n    Logger: {\n      // Everything below is optional\n      level: LogLevelName,\n      labels: {\n        // You can define only the labels you want to change from the default\n        error: string,\n        warn: string,\n        info: string,\n        debug: string,\n      },\n      useSyslog: boolean, // Only used on iOS\n    },\n  },\n}\n```\n\nConfig values are read in `Logger` constructors that are passed a plugin, and are overridden by any config options you pass to the constructor.\n\n## API\n\nThe functionality of `Logger` is the same on each of the three platforms, but the API is slightly different.\n\n### Web (TypeScript)\n\n```typescript\nenum LogLevel {\n  silent,\n  error,\n  warn,\n  info,\n  debug\n}\n\n// This resolves to the type union 'error' | 'warn' | 'info' | 'debug'\ntype LogLevelName = Exclude\u003ckeyof typeof LogLevel, 'silent'\u003e\n\n// Returned by the .labels getter and passed to the setter.\n// It's a map of level names to corresponding labels.\ntype LogLevelMap = { [key in LogLevelName]?: string }\n\n// Options passed to the constructor\ninterface Options {\n  level?: LogLevel\n  labels?: LogLevelMap\n  useSyslog?: boolean  // only used on iOS\n}\n\nclass Logger {\n\tconstructor(tag: string, options?: Options) {}\n\n  // Get the current log level for this logger\n  get level(): LogLevel {}\n\n  // Set the current log level for this logger\n  set level(level: LogLevel | string) {}\n\n  // Get the current log level as a string\n  get levelName(): string {}\n\n  // Set the current log level as a string.\n  // If the name is invalid, it is ignored.\n  set levelName(level: string) {}\n\n  // Returns the LogLevel enum for the given name,\n  // or undefined if the name is invalid.\n  getLevelWithName(name: string): LogLevel | undefined {}\n\n  // Returns a copy of a map between log level names and labels\n  get labels(): LogLevelMap {}\n\n  // Sets the mapping between log level names and labels.\n  // Invalid level names or empty labels are ignored.\n  set labels(labels: LogLevelMap) {}\n\n  // Get the current log tag\n  get tag(): string {}\n\n  // Set the current log tag. If `tag` is empty, it is ignored.\n  set tag(tag: string) {}\n\n  // The following methods log a message at the given level.\n  // This is the main interface you will use to the `Logger` class.\n\n  // Unlike `console.\u003clevel\u003e`, if the current log level of the logger\n  // is less than the level of the method, the message is ignored.\n\n  // Also unlike `console.\u003clevel\u003e`, you can only pass a single parameter.\n  // The multi-parameter console methods were created in the days\n  // before we had template strings, so a single string is enough.\n\n  // silent() is there to facilitate dynamically calling\n  // a logging method based on the level name without needing\n  // to special-case 'silent'.\n  silent(message: string) {}\n  error(message: string) {}\n  warn(message: string) {}\n  info(message: string) {}\n  log(message: string) {}  // alias for info()\n  debug(message: string) {}\n\n  // Logs a message at the given level. If `level` is\n  // an invalid level name, the level defaults to info.\n  logAtLevel(level: LogLevel | string, message: string) {}\n\n  // Same as `logAt`, but you can also specify the tag.\n  logWithTagAtLevel(level: LogLevel | string, tag: string, message: string) {}\n\n  // Logs a debug representation of a value at the info level.\n  dir(item: unknown) {}\n\n  // Clears the console on the web, does nothing on native platforms.\n  clear() {}\n\n  // These are the exact equivalents of the console timer methods,\n  // but are implemented on all platforms.\n  time(label?: string | undefined) {}\n  timeLog(label?: string) {}\n  timeEnd(label?: string) {}\n\n  // These methods are passed through to `console` on the web\n  // and do nothing on native platforms.\n  count(label?: string | undefined) {}\n  countReset(label?: string | undefined) {}\n  group(...label: any[]) {}\n  groupCollapsed(...label: any[]) {}\n  groupEnd() {}\n  table(tabularData: any, properties?: readonly string[] | undefined) {}\n\n  // Logs a stack trace at the current point of execution\n  trace() {}\n\n  // Returns whether logging should be routed to the system log on iOS.\n  get useSyslog(): boolean {}\n\n  // Sets whether logging should be routed to the system log on iOS.\n  set useSyslog(use: boolean) {}\n```\n\n### iOS (Swift)\n\n```swift\npublic class Logger {\n  public enum LogLevel: Int {\n    case silent = 0\n    case error\n    case warn\n    case info\n    case debug\n\n    // The equivalent of `getLevelWithName()` in TypeScript.\n    // Returns the LogLevel with the given name, or nil if invalid.\n    public static subscript(_ str: String) -\u003e LogLevel? {}\n  }\n\n  // Use this to pass options to the Logger initializer\n  public struct Options {\n    public var level: LogLevel?\n    public var labels: [String: String]?\n    public var useSyslog: Bool?\n\n    // Initializer for Options\n    public init(\n      level: LogLevel = LogLevel.info,\n      labels: [String: String] = [:],\n      useSyslog: Bool = false\n    ) {}\n  }\n\n  // The exact equivalent of `labels` property in TypeScript. Lets you\n  // get and set level labels as a map of level names to labels.\n  public var labels: [String: String]\n\n  // The current log level\n  public var level: LogLevel\n\n  // The current log tag. When setting, an empty tag is ignored.\n  public var tag: String\n\n  // Whether to log to the system log, defaults to false\n  public var useSyslog: Bool\n\n  // Initialize a logger with the given app delegate using the\n  // app's bundle display name as the tag and reading config from disk\n  // (see Configuration above).\n  public convenience init(\n    withAppDelegate delegate: UIApplicationDelegate,\n    options: Options? = nil\n  ) {}\n\n  // Initialize a logger with the given plugin, using the plugin's name as the tag,\n  // and reading config from disk (see Configuration above).\n  public convenience init(withPlugin plugin: CAPPlugin, options: Options?) {}\n\n  // Initialize a logger with the given tag and options.\n  public convenience init(\n    withTag tag: String,\n    options: Options? = nil\n  ) {}\n\n  // Level logging methods\n  public func error(_ message: String) {}\n  public func warn(_ message: String) {}\n  public func info(_ message: String) {}\n  public func log(_ message: String) {}  // alias for info()\n  public func debug(_ message: String) {}\n\n  // Generic logging methods\n  public func log(atLevel level: LogLevel, message: String) {}\n  public func log(\n    atLevel: level: LogLevel,\n    label: String?,\n    tag: String,\n  \tmessage: String) {}\n\n  // Log a debug representation of a value at info level\n  public func dir(_ value: Any?) {}\n\n  // Implementation of the console timer methods\n  public func time(_ label: String?) {}\n  public func timeLog(_ label: String?) {}\n  public func timeEnd(_ label: String?) {}\n\n  // Logs a stack trace at the current point of execution on all platforms\n  public func trace() {}\n}\n```\n\n### Android (Java)\n\n```java\npublic class Logger {\n\n  public enum LogLevel {\n    silent,\n    error,\n    warn,\n    info,\n    debug,\n  }\n\n  // Options passed to Logger constructor\n  public static class Options {\n\n    LogLevel level;\n    Map\u003cString, String\u003e labels;\n\n    // Make default options: level = info, labels = null\n    Options() {}\n\n    // Copy constructor\n    Options(Options other) {}\n\n    Options(LogLevel level) {}\n\n    Options(Map\u003cString, String\u003e labels) {}\n\n    Options(LogLevel level, Map\u003cString, String\u003e labels) {}\n  }\n\n  // The current log level\n  public LogLevel level;\n\n  // Construct a logger with the given activity, using the apps's display\n  // name as the tag, log level of info, default labels, and reading config\n  // from disk (see Configuration above).\n  public Logger(@NonNull BridgeActivity activity) {}\n\n  // Same as above, but passing options that will override level and labels\n  public Logger(@NonNull BridgeActivity activity, Options options) {}\n\n  // Construct a logger with the given plugin, using the plugin's name as the tag,\n  // log level of info, default labels, and reading config from disk\n  // (see Configuration above).\n  public Logger(Plugin plugin) {}\n\n  // Same as above, but passing options that will override level and labels\n  public Logger(Plugin plugin, Options options) {}\n\n  // Construct a logger with the given tag and default level and labels\n  public Logger(String tag) {}\n\n  // Same as above, but passing options that will override level and labels\n  public Logger(String tag, Options options) {}\n\n  // Return the LogLevel with the given name, or null if invalid\n  @Nullable\n  public Object getLevelWithName(String name) {}\n\n  // Return the name of the current log level\n  public String getLevelName() {}\n\n  // Set the current level by name. Invalid names are ignored.\n  public void setLevelName(String name) {}\n\n  // Return a map of level names to level labels\n  public Map\u003cString, String\u003e getLabels() {}\n\n  // Set level labels given a map of level names to labels.\n  // Invalid level names are ignored.\n  public void setLabels(Map\u003cString, String\u003e labels) {}\n\n  // Return the current tag\n  public String getTag() {}\n\n  // Set the tag. An empty string is ignored.\n  public void setTag(String tag) {}\n\n  // Level logging methods\n  public void error(String message) {}\n\n  public void warn(String message) {}\n\n  public void info(String message) {}\n\n  public void log(String message) {} // alias for info()\n\n  public void debug(String message) {}\n\n  // Generic logging\n  public void logAtLevel(LogLevel level, String message) {}\n\n  public void logWithTagAtLevel(LogLevel level, String tag, String message) {}\n\n  public void logWithTagAtLevel(\n    LogLevel level,\n    String label,\n    String tag,\n    String message\n  ) {}\n\n  // Generic logging. If level is an invalid level name, defaults to info.\n  public void logAtLevel(String level, String message) {}\n\n  public void logWithTagAtLevel(String level, String tag, String message) {}\n\n  // Log a debug representation of a value at info level\n  public void dir(Object value) {}\n\n  // Implementation of the console timer methods\n  public void time() {}\n\n  public void time(String label) {}\n\n  public void timeLog() {}\n\n  public void timeLog(String label) {}\n\n  public void timeEnd() {}\n\n  public void timeEnd(String label) {}\n\n  // Logs a stack trace at the current point of execution on all platforms\n  public void trace() {}\n}\n\n```\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faparajita%2Fcapacitor-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faparajita%2Fcapacitor-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faparajita%2Fcapacitor-logger/lists"}