https://github.com/mpyw/cloudwatch-front-logger
Save your browser console logs to AWS CloudWatch (Inspired by agea/console-cloud-watch)
https://github.com/mpyw/cloudwatch-front-logger
aws-cloudwatch cloudwatch cloudwatch-logs javascript typescript
Last synced: about 1 year ago
JSON representation
Save your browser console logs to AWS CloudWatch (Inspired by agea/console-cloud-watch)
- Host: GitHub
- URL: https://github.com/mpyw/cloudwatch-front-logger
- Owner: mpyw
- License: mit
- Archived: true
- Created: 2019-12-07T21:01:51.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-20T07:26:54.000Z (over 3 years ago)
- Last Synced: 2025-03-15T01:51:49.469Z (about 1 year ago)
- Topics: aws-cloudwatch, cloudwatch, cloudwatch-logs, javascript, typescript
- Language: TypeScript
- Homepage:
- Size: 47.9 KB
- Stars: 17
- Watchers: 2
- Forks: 6
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CloudWatch Front Logger [](https://badge.fury.io/js/cloudwatch-front-logger) [](https://github.com/mpyw/cloudwatch-front-logger/actions) [](https://coveralls.io/github/mpyw/cloudwatch-front-logger?branch=master) [](https://www.npmjs.com/package/cloudwatch-front-logger)
Save your browser console logs to AWS CloudWatch (Inspired by [agea/console-cloud-watch](https://github.com/agea/console-cloud-watch))
- Demo: [mpyw/cloudwatch-front-logger-demo](https://github.com/mpyw/cloudwatch-front-logger-demo)
## Installing
```
npm i cloudwatch-front-logger
```
## Preparation
### 1. Create Public Log Group
Go to [CloudWatch console](https://console.aws.amazon.com/cloudwatch) and create Log Group for this purpose.
### 2. Create Policy
Go to [IAM Console](https://console.aws.amazon.com/iam/home) and create restricted policy for CloudWatch Logs.
- `logs:CreateLogStream`
- `logs:PutLogEvents`
```json5
{
"Version": "2019-12-08",
"Statement": [
{
"Sid": "CloudWatchFrontLoggerSid",
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:*:*:log-group::*:*",
"arn:aws:logs:*:*:log-group:"
]
}
]
}
```
### 3. Create IAM user
Go to [IAM Console](https://console.aws.amazon.com/iam/home) and create user with the restricted policy.
## Basic Usage
```js
import { Logger } from 'cloudwatch-front-logger'
const accessKeyId = 'XXXXXXXXXXXXXXXXXXXX'
const secretAccessKey = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
const region = 'ap-northeast-1'
const logGroupName = ''
const logger = new Logger(accessKeyId, secretAccessKey, region, logGroupName)
logger.install()
```
Logs are collected from the following sources.
- Uncaught Error
- `console.error()` call
- Manual `logger.onError()` call
(See integration examples)
## Advanced Usage
### Personalize LogStream
By default, `"anonymous"` is used for `logStreamName` value.
If you wish allocating a unique stream for each user, you can use a method such as [Canvas Fingerprint](https://github.com/Valve/fingerprintjs2).
Pass a resolver function as **`logStreamNameResolver`** option value on `install()` call.
```js
import FingerprintJS from 'fingerprintjs'
logger.install({
async logStreamNameResolver() {
const fp = await FingerprintJS.load()
const { visitorId } = await fp.get()
return visitorId
},
})
```
### Customize Formatted Message
Filter Errors
By default, messages are formatted into **JSON** string which has `message` and `type`.
```json5
{
"message": "Err: Something went wrong",
"type": "uncaught"
}
```
```json5
{
"message": "Something went wrong",
"type": "console",
"level": "error"
}
```
If you wish formatting them by yourself, pass a formatter function as **`messageFormatter`** option value on `install()` call. Note that you can cancel by returning **`null`** from the fuunction.
```js
import StackTrace from 'stacktrace-js'
logger.install({
async messageFormatter(e, info = { type: 'unknown' }) {
if (!e.message) {
return null
}
let stack = null
if (e.stack) {
stack = e.stack
try {
stack = await StackTrace.fromError(e, { offline: true })
} catch (_) {
}
}
return JSON.stringify({
message: e.message,
timestamp: new Date().getTime(),
userAgent: window.navigator.userAgent,
stack,
...info,
})
},
})
```
### Use Asynchronous Storage instead of `localStorage`
By default, **`localStorage`** is used for caching `logStreamName` and `nextSequenceToken`.
Still `localStorage` has only synchronous API, asynchronous interfaces are also supported.
If you need to change storage implementation from `localStorage`, pass an instance as **`storage`** option value on `install()` call.
```js
import { AsyncStorage } from 'react-native'
logger.install({
storage: AsyncStorage,
})
```
## Integration Examples
### React (Component)
```jsx
class LoggerComponent extends React.component {
componentDidCatch(e, info) {
this.props.logger.onError(e, {
...info,
type: 'react',
})
}
render() {
return this.props.children
}
}
```
```jsx
```
### Redux (Middleware)
```js
const createLoggerMiddleware = (logger) => (store) => (next) => (action) => {
try {
return next(action)
} catch (e) {
logger.onError(e, {
action,
type: 'redux',
})
}
}
```
```js
const store = createStore(
combineReducers(reducers),
applyMiddleware(createLoggerMiddleware(logger))
)
```