Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,4 @@ out
*.d.ts
dist
build
storage
214 changes: 154 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,102 +31,196 @@ npm install @secjs/logger

## Usage

### Config logging template

> First you need to create the configuration file logging in the config folder on project root path. Is extremely important to use export default in these configurations.

```ts
import { Env } from '@secjs/env'
import { Path } from '@secjs/utils'

export default {
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration object.
|
*/

default: Env('LOGGING_CHANNEL', 'application'),

/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application.
|
| Available Drivers: "console", "debug", "file".
| Available Formatters: "context", "debug", "json", "log".
|
*/

channels: {
application: {
driver: 'console',
context: 'Logger',
formatter: 'context',
},
debug: {
driver: 'debug',
context: 'Debugger',
formatter: 'context',
namespace: 'api:main',
},
file: {
driver: 'file',
context: 'Logger',
formatter: 'log',
filePath: Path.noBuild().logs('secjs.log'),
},
},
}
```

### Log / Logger

> Log any type of requests in your application in public mode
> With the config/logging file created you can use Log and Logger classes to start logging.

```ts
import { Log, Logger } from '@secjs/logger'
import { Log, Logger, Color } from '@secjs/logger'

Log('Hello World!')
// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Log] Hello World! +0ms
// Log and Logger will always use the default values of channel inside config/logging, the default channel in here is "application".
Log.log('Hello World!')
// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Logger] Hello World! +0ms

const logger = new Logger('LogService')
const logger = new Logger()

logger.success('Hello World!')
// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [LogService] Hello World! +0ms
// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Logger] Hello World! +0ms

logger.warn('Hello World!', { context: 'LogController' })
// You can pass options to formatters and drivers as second parameter
logger.warn('Hello World!', { color: Color.purple, context: 'LogController' })
// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [LogController] Hello World! +0ms
```

### Formatters / Transporters / LogMapper
### Using other channels

> Use transporters and formatters to keep a pattern in how the application will handle the logs. And use mappers
> to set formatters and transporters that are going to be used. See the example:
> You can use any channel that you configure inside config/logging, SecJS has default channels inside the template file.

```ts
import {
LogMapper,
JsonFormatter,
FileTransporter,
ContextFormatter,
changeLogFnMapper,
ConsoleTransporter,
} from '@secjs/logger'

const logMapper = new LogMapper([new JsonFormatter()], [new FileTransporter()])

// This function is important to change the default mapper from Log function
changeLogFnMapper(logMapper)
const logger = new Logger('Context', logMapper)

// You can use addFormatter and addTransporter to add more formatters and transporters
logMapper.addFormatter(new ContextFormatter('Context'))
logMapper.addTransporter(new ConsoleTransporter('stdout'))

// You can use removeFormatter and removeTransporter too.
logMapper.removeFormatter(ContextFormatter)
logMapper.removeTransporter(ConsoleTransporter)
Log.channel('debug').log('Hello debug world!', { namespace: 'api:example' })
// api:example [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Debugger] Hello debug world! +0ms
```

> Now Log function and Logger class will use the logMapper instance,
> all logs will be stringify by JsonFormatter, and be saved inside FileTransporter.

### Custom formatters and transporters

> Here are all the already implemented formatters and transporters from @secjs/logger
> You can use many channels to handle the log in all of then

```ts
import {
LogFormatter,
JsonFormatter,
DebugFormatter,
ContextFormatter,
FileTransporter,
DebugTransporter,
ConsoleTransporter,
} from '@secjs/logger'
Log.channels('debug', 'application', 'file').info('Hello World!', { namespace: 'api:example' })
// api:example [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Debugger] Hello World! +0ms
// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Logger] Hello World! +0ms

// In storage/logs/secjs.log file
// [SecJS] - PID: 196416 - dd/mm/yyyy, hh:mm:ss [INFO] Hello World!
```

> You can define your own formatters and transporters using the contracts
### Extending drivers, channels and formatters

> Nowadays, @secjs/logger has only FileDriver, DebugDriver and ConsoleDriver support, but you can extend the drivers for Logger class if you implement DriverContract interface.

```ts
import { FormatterContract, TransporterContract } from '@secjs/logger'
import { DriverContract, FormatterContract, format } from '@secjs/logger'

interface CustomDriverOpts {}

export class CustomFormatter implements FormatterContract {
format(message: any, options?: any) {
createFileToTransportToS3(message, options.filePath)
class CustomDriver implements DriverContract {
private readonly _level: string
private readonly _context: string
private readonly _formatter: string

constructor(channel: string) {
const config = Config.get(`logging.channels.${channel}`)

deleteTheFile(options.filePath)
this._level = config.level || 'INFO'
this._context = config.context || 'CustomDriver'
this._formatter = config.formatter || 'context'
}

transport(message: string, options?: CustomDriverOpts): void {
options = Object.assign(
{},
{
level: this._level,
context: this._context,
streamType: this._streamType,
},
options,
)

message = format(this._formatter, message, options)

process[this._streamType].write(`${message}\n`)
}
}
```

> Same to extend formatters

```ts
class CustomFormatter implements FormatterContract {
// all the methods implemented from FormatterContract...
}
```

export class CustomTransporter implements TransporterContract {
transport(logFormatted: any, options?: any) {
sendToS3(logFormatted, options.s3Bucket)
> Constructor is extremely important in your CustomDriver class, it's the constructor that will use the values from config/logging channels to manipulate your CustomDriver using channel and channels method from logger.
> So if you are building a CustomDriver, and you want to use it, you can create a new channel inside config/logging channels or change the driver from an existing channel.

```ts
// extending channels
// config/logging file

export default {
// default etc...

channels: {
mychannel: {
driver: 'custom',
level: 'INFO',
formatter: 'context',
context: 'Logger',
}
// ... other disks
}
}
```

> Then, use it with the mappers
> Now you can build your new driver using Logger class

```ts
import { LogMapper } from '@secjs/logger'
const driverName = 'custom'
const formatterName = 'custom'
const driver = CustomDriver
const formatter = CustomFormatter

const s3LogMapper = new LogMapper([new CustomFormatter()], [new CustomFormatter()])
Logger.buildDriver(driverName, driver)
Logger.buildFormatter(formatterName, CustomFormatter)

console.log(Logger.drivers) // ['console', 'debug', 'file', 'custom']
console.log(Logger.formatters) // ['context', 'debug', 'json', 'log', 'custom']
```

> Now, if you have implemented your channel in config/logging, you can use him inside logger

```ts
// options of your driver and formatter
const options = {}

const s3Logger = new Logger('S3LoggerService', s3LogMapper)
// Will use CustomDriver to handle the log actions
logger.channel('mychannel').success('Hello World!!', options)
```

---
Expand Down
49 changes: 49 additions & 0 deletions config/logging.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Env } from '@secjs/env'
import { Path } from '@secjs/utils'

export default {
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration object.
|
*/

default: Env('LOGGING_CHANNEL', 'application'),

/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application.
|
| Available Drivers: "console", "debug", "file".
| Available Formatters: "context", "debug", "json", "log".
|
*/

channels: {
application: {
driver: 'console',
context: 'Logger',
formatter: 'context',
},
debug: {
driver: 'debug',
context: 'Debugger',
formatter: 'context',
namespace: 'api:main',
},
file: {
driver: 'file',
context: 'Logger',
formatter: 'log',
filePath: Path.noBuild().logs('secjs.log'),
},
},
}
23 changes: 11 additions & 12 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
export * from './src/utils/Color'
export * from './src/utils/getTimestamp'

export * from './src/Logger/Log'
export * from './src/Logger/Logger'
export * from './src/Logger/LogMapper'
export * from './src/Logger/defaultMapper'

export * from './src/Contracts/DriverContract'
export * from './src/Contracts/FormatterContract'
export * from './src/Contracts/TransporterContract'

export * from './src/Drivers/FileDriver'
export * from './src/Drivers/DebugDriver'
export * from './src/Drivers/ConsoleDriver'

export * from './src/Formatters/LogFormatter'
export * from './src/Formatters/JsonFormatter'
export * from './src/Formatters/DebugFormatter'
export * from './src/Formatters/ContextFormatter'

export * from './src/Transporters/FileTransporter'
export * from './src/Transporters/DebugTransporter'
export * from './src/Transporters/ConsoleTransporter'
export * from './src/utils/Color'
export * from './src/utils/format'
export * from './src/utils/getTimestamp'

export * from './src/Log'
export * from './src/Logger'
Loading