{"id":20388611,"url":"https://github.com/efureev/js-logger","last_synced_at":"2026-04-19T02:32:33.909Z","repository":{"id":50657397,"uuid":"464152228","full_name":"efureev/js-logger","owner":"efureev","description":"JS Logger for browser and etc..","archived":false,"fork":false,"pushed_at":"2022-10-15T11:38:43.000Z","size":1257,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T12:42:27.004Z","etag":null,"topics":["browser","log","logger","logging"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/efureev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-27T14:00:03.000Z","updated_at":"2022-08-09T05:33:13.000Z","dependencies_parsed_at":"2022-09-06T14:12:20.733Z","dependency_job_id":null,"html_url":"https://github.com/efureev/js-logger","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/efureev/js-logger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/efureev%2Fjs-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/efureev%2Fjs-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/efureev%2Fjs-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/efureev%2Fjs-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/efureev","download_url":"https://codeload.github.com/efureev/js-logger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/efureev%2Fjs-logger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31991982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["browser","log","logger","logging"],"created_at":"2024-11-15T03:11:48.422Z","updated_at":"2026-04-19T02:32:33.849Z","avatar_url":"https://github.com/efureev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Browser Logger\n\n[![CI: logger](https://github.com/efureev/js-logger/actions/workflows/nodejs.yml/badge.svg?branch=master)](https://github.com/efureev/js-logger/actions/workflows/nodejs.yml)\n[![codecov](https://codecov.io/gh/efureev/js-logger/branch/main/graph/badge.svg?token=z2Xa7u7PYu)](https://codecov.io/gh/efureev/js-logger)\n[![NPM version](https://img.shields.io/npm/v/@feugene/browser-logger?style=flat-square)](https://www.npmjs.com/package/@feugene/browser-logger)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square)](https://conventionalcommits.org)\n\n## Install\n\n```shell\nyarn add @feugene/browser-logger\n```\n\n## Example in Browsers\n\n| Chrome                         | Safari                         |\n|--------------------------------|--------------------------------|\n| ![Chrome](./.media/chrome.png) | ![Chrome](./.media/safari.png) |\n| ![](./.media/screenshot.png)   | ![](./.media/scr2.png)         |\n\n\n## Use\n\n### Basic use\n\n```js\nimport { BrowserLogger } from '@feugene/browser-logger'\n\nconst logger = new BrowserLogger()\n\n// ...\n\nlogger.log('test')\nlogger.info('test', 'prefix', 3)\nlogger.error(new Message('test'))\n```\n\n### Advanced use\n\n```js\nimport { Logger, ConsoleDriver, ColorCollection, LEVEL_INFO } from '@feugene/browser-logger'\n\nconst logger = new Logger(\n  new Logger({\n    driver: new ConsoleDriver(),\n    colors: new ColorCollection({ // colors map\n      black: '#000000',\n      red: '#EC5f67',\n      yellow: '#FAC863',\n      green: '#99C794',\n      blue: '#6699CC',\n      white: '#FFFFFF',\n    }),\n    level: LEVEL_INFO\n  })\n)\n\n// ...\n\nthis.logger.panel('Title', {\n  bgColor: 'yellow', // =\u003e '#FAC863'\n  color: 'teal', // =\u003e 'teal' because it absents in color map\n  offset: 5,\n})\n\n// ...\n\nconst msg = new Message()\nmsg.pushBlock(MessageBlock.instance('prefix').color('#FFF').background('#00FFAA').paddingLeft(2))\nmsg.pushBlock(MessageBlock.instance('Basic text', { color: this.logger.getColors() }).color('red'))\nlogger.log(msg)\n```\n\n### Deep Advanced use\n\nYou can use your logger-wrapper with your custom panels:\n\n```js\nimport { BrowserLogger, colors } from '@feugene/browser-logger'\n\nexport default class Logger {\n  constructor(level) {\n    this.logger = BrowserLogger(level)\n\n    return new Proxy(this, {\n      get(target, prop) {\n        if (prop in target) {\n          return target[prop]\n        }\n        return target.logger[prop]\n      },\n    })\n  }\n\n  warning(text, title = '⚠️ warning', offset = 0) {\n    return this.logger.panel(\n      title,\n      { bgColor: colors.orange, color: colors.white, offset },\n      text\n    )\n  }\n\n  info(text, title = 'info', offset = 0) {\n    return this.logger.panel(title, { bgColor: colors.teal, offset }, text)\n  }\n\n  error(text, title = '🆘 error', offset = 0) {\n    return this.logger.panel(\n      title,\n      { bgColor: colors.red, color: colors.white, offset },\n      text\n    )\n  }\n}\n```\n\nAnd use it:\n\n```js\nimport { Message, MessageBlock, colors } from '@feugene/browser-logger'\n\n{\n  // ...\n  this.logger = new Logger()\n\n  this.logger.warning('MessageBlock', undefined, 4)\n  this.logger.warning('MessageBlock', 'ALERT')\n  this.logger.error('MessageBlock')\n  this.logger.error('MessageBlock')\n  this.logger.info('Info', 'text')\n\n  this.logger.panel('Title', undefined, 'Post Text')\n  this.logger.panel('Title', {}, 'Post Text')\n  this.logger.panel('Title', {\n    bgColor: '#5FB3B3',\n    color: '#1B2B34',\n    offset: 5,\n  })\n\n  const colors = this.logger.getColors()\n  const msg = Message.instance().pushBlock(\n    MessageBlock.instance('panel 1', { colors: colors })\n      .background('green')\n      .borderRadius(3)\n      .offsetLeft(1)\n      .padding(2, 4),\n\n    MessageBlock.instance('panel 2')\n      .background(colors.get('blue'))\n      .offsetLeft(1)\n      .padding(2, 4),\n\n    MessageBlock.instance('panel 3')\n      .background('#000')\n      .color('#fff')\n      .borderRadius(10)\n      .offsetLeft(5)\n      .padding(2, 4),\n\n    MessageBlock.instance('4 330')\n      .background(colors.get('purple'))\n      .color('#fff')\n      .borderRadius(10)\n      .offsetLeft(5)\n      .padding(2, 20)\n  )\n\n  this.logger.log(msg)\n\n  this.logger.panel('Title', {\n    bgColor: '#5FB3B3',\n    color: 'gray',\n    offset: 5,\n  })\n}\n```\n\n## Features\n\n### Log levels\n\nThe Logger logs messages by `Log Levels`.\n\nThere are 4 message types:\n\n- Error\n- Info\n- Debug\n- Trace\n\n- There are 4 log levels:\n\n- `LEVEL_ERROR` - Log only `Error` type messages\n- `LEVEL_INFO` - Log only `Error` and `Info` type messages\n- `LEVEL_DEBUG` - Log only `Error`, `Info` and `Debug` type messages\n- `LEVEL_TRACE` - Log only `Error`, `Info`,`Debug` and `Trace` type messages\n- `LOG_ALL` - It's an alias of `LEVEL_TRACE`\n\nYou may define log level of your Logger. By default, log level is `LOG_ALL`.  \nYou may point your own Log level:\n\n```js\nlogger.setLevel(INFO | DEBUG) // will be logs only `info` \u0026 `debug` messages\n```\n\n### Methods\n\n**Basic**\n\n```js\nconst logger = new BrowserLogger(level)\n\nlogger.log()\nlogger.error()\nlogger.info()\nlogger.debug()\nlogger.trace()\n```\n\n**Panel**\n\n```js\nconst logger = new BrowserLogger(level)\n\nlogger.panel(\n  'App',\n  { bgColor: 'red', color: 'white', offset: 2 },\n  'description',\n  'error'\n)\n```\n\n**Panels**\n\n```js\nconst logger = new BrowserLogger(level)\n\nlogger.panels(\n  'info',\n  { text: 'panel 1', bgColor: 'teal', color: 'yellow', borderRadius: 5 },\n  { text: 'panel 2', color: 'white' },\n  { text: 'panel 3', color: 'red', offset: 2, padding: 1 }\n)\n\nlogger.panels(\n  'trace',\n  {\n    text: 'App',\n    bgColor: 'grayLight',\n    color: 'gray',\n    offsetLeft: 2,\n    borderRadius: 3,\n    padding: [2, 4],\n  },\n  'description'\n)\n```\n\n### Debugging\n\n```js\nconst defaultBlockConfig = {\n  offsetLeft: 1,\n  offsetRight: 1,\n  borderRadius: 3,\n  padding: [2, 4],\n}\n\nconst panel = {\n  ...defaultBlockConfig,\n  bgColor: 'gray',\n  color: 'white',\n}\n\nconst makePanel = (text, panelConfig) =\u003e ({\n  text,\n  ...panel,\n  ...panelConfig,\n})\nconst prefixPanels = (prefix, ...panels) =\u003e logger.panels(\n  prefix,\n  makePanel('Application', { offsetLeft: 10 }),\n  ...panels.map((panel) =\u003e {\n    if (typeof panel === 'string') {\n      return panel\n    }\n\n    return {\n      padding: [2, 4],\n      ...panel,\n    }\n  })\n)\n\nconst names = ['first', 'second']\nlogger.enableDebug()\n// or `logger.enableDebug({ printFragmented: true })`\n// or `logger.enableDebug({ debugFn: console.log })`\n// or `logger.enableDebug({ debugFn: logger.getDriver().output.log })`\n\nprefixPanels(\n  'trace',\n  'Booter',\n  4,\n  'booted plugins',\n  ...names.map((text) =\u003e this.logger.makeNamedPanel(text, 'tealLabel'))\n)\n\nlogger.disableDebug()\n```\n\n### Return a result\n\n```js\n\nconst list: string[] = logger.returnResult().panels('info',\n  { text: 'panel 1', bgColor: 'teal', color: 'yellow', borderRadius: 5 },\n  { text: 'panel 2', color: 'white' },\n  { text: 'panel 3', color: 'red', offsetLeft: 2, padding: 1 }\n)\n\nlist === [\n  '%cpanel 1%cpanel 2%cpanel 3',\n  'background:#5FB3B3;color:#FAC863;border-radius:5px;',\n  'color:#FFFFFF;',\n  'color:#ff000f;margin-left:20px;padding:1px;'\n]\n```\n\n### Group collapsed\n\n```js\nlogger.groupCollapsed(\n  { text: 'Collapse panel', bgColor: 'teal', color: 'yellow', borderRadius: 5 },\n  ['text1', 'text2']\n)\n```\n\n```js\nconst message = Message.instance({ text: 'ERROR', color: 'red' })\nmessage.pushBlock(\n  MessageBlock.instance({ text: 'Fatal Error', bgColor: 'red', color: 'white', borderRadius: 5 }),\n  MessageBlock.instance('description')\n)\n\nlogger.groupCollapsed(message, ['text1', 'text2'])\n```\n\n**From error**\n\n```js\nconst error = new Error('Custom error')\nerror.stack = 'line 1\\nline 2'\n\n// with stack collapsed\nlogger.error(\n  error.title,\n  { text: 'Error', bgColor: 'red', borderRadius: 5 },\n  error\n)\n\n// or simple error\nlogger.error(\n  'Error Title',\n  { text: 'Error', bgColor: 'red', borderRadius: 5 }\n)\n```\n\nExample of this:\n\n`Collapsed view`\n![](./.media/error-collapsed.png)\n\n`Expanded view`\n![](./.media/error-expanded.png)\n\n```js\nconst error = new Error('Custom error')\nconst message = Message.instance(\n  this.makeBasicPanel('ERROR', 1, { color: 'red' }),\n  this.logger.getColors()\n)\n\nmessage.pushBlock(\n  MessageBlock.instance(\n    this.makeNamedPanel(title, 'red', { color: 'white' })\n  ),\n  MessageBlock.instance(text, { colors: this.logger.getColors() })\n)\n\nthis.logger.error(message, '', error)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fefureev%2Fjs-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fefureev%2Fjs-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fefureev%2Fjs-logger/lists"}