mongoose delete & winston

Mongoose Populate

Mongoose Delete 插件

功能

  • 添加了 delete() 方法。
  • 添加了 deleteById() 方法。
  • 在documents上添加了 deleted 这个属性(Boolean)
  • 添加deteledAt属性用来保存删除的时间。
  • 添加deletedBy属性来记录谁删除了document。
  • 使用restore回复已经删除的文档。
  • 批量删除和恢复。
  • 可选择是否重写静态的方法(count, countDocuments, find, findOne, findOneAndUpdate, update, updateMany))
  • 对于可重写的方法额外提供了两个方法: methodDeleted,methodWithDeleted
  • 在删除时禁用模型的校验
  • 可选择 在删除的fields创建索引
  • 可选择是否禁用 $ne操作符 通过使用{use$neOperator: false}

使用

mongoose中的删除操作有 remove, findByIdAndRemove, findOneAndRemove.这些方法都不会执行软删除

对于删除操作,要是用deletedeleteById方法来删除数据是软删除。

谁删除了数据。 添加 {deletedBy : true } link

重写方法

可选择重写所有或者指定的方法。

目的: 重写方法将排除掉删除的document,(删除的document都有deleted = true)

每个重写的方法都会有两个额外的方法。(methodDeleted,methodWithDeleted

支持的可选重写方法。 ['count', 'countDocuments', 'find', 'findOne', 'findOneAndUpdate', 'update', 'updateMany', ]

find方法为例。

配置为


{

overrideMethods: ['find']

}

除了find方法以外会有findDeleted,findWithDeleted

  • find 方法返回所有除了deleted=false的数据
  • findDeleted 方法返回所有delted=true的数据
  • findWithDeleted返回所有数据

删除时禁用model的校验

默认情况下,该插件开启校验。


Schema.plugin(mongoose_delete)

Schema.plugin(mongoose_delete,{

validateBeforeDelete: true

})

validateBeforeDelete设置为false,就不会校验

创建索引


PetSchema.plugin(mongoose_delete, { indexFields: 'all' });

// or

PetSchema.plugin(mongoose_delete, { indexFields: true });

对于deleted,deletedAt,deletedBy三个字段都添加索引


// Index only specific fields

PetSchema.plugin(mongoose_delete, { indexFields: ['deleted', 'deletedBy'] });

// or

PetSchema.plugin(mongoose_delete, { indexFields: ['deletedAt'] });

对指定的字段添加索引。(指定也是在3者之间)

winston 日志模块

levels


const levels = {

error: 0,

warn: 1,

info: 2,

http: 3,

verbose: 4,

debug: 5,

silly: 6

};

winston.createLogger参数


const logger = winston.createLogger({

transports: [

new winston.transports.Console(),

new winston.transports.File({ filename: 'combined.log' })

]

});

如上代码可以创建一个Logger.

参数

  • level 默认info 只记录 小于等于info级别的日志。
  • levels 默认``,日志的优先级别和颜色
  • format 格式化
  • transports 日志的输出目标,可以是文件,控制台,http服务,或者流
  • exitOnError true ,如果设置为false,处理到的异常不会造成 退出
  • silent false,如果为真,所有异常都被禁用

winston.formats

winston.formats由这个三方库实现logform


const alignedWithColorsAndTime = format.combine(

format.colorize(), // info.level在控制台中输出会有颜色

format.timestamp(), // 添加这个后,info中会有timestamp属性

format.align(),

format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)

);

关于info对象,format.printf中的info就是info对象。

它至少有两个属性 level,message.

format.colorize,format.timestamp 这些被称为format。那format是什么呢,实际上是对info的进一层加工,返回一个更改过后的info


const { format } = require('logform');

const volume = format((info, opts) => {

if (opts.yell) {

info.message = info.message.toUpperCase();

} else if (opts.whisper) {

info.message = info.message.toLowerCase();

}

return info;

});

多个format可以通过format.combine合并成一个。正如上边第一个demo中使用的方法一样。

一些内置的format
  • align 对齐
  • colorize 着色

format.colorize({

colors: {

info: "red"

}

}),
  • combine 合并多个format
  • errors
  • json
  • label 一个label标签 [label]....

format.label({

label: ""

})
  • Logstash 转成纯json对象
  • Metadata 除了level和message属性,其它都放入到meta属性下边
  • padLevels 格式长度相同
  • PrettyPrint 这个最好不要在生产模式使用
  • simple 简单的模式

const { format } = require('logform');

const MESSAGE = Symbol.for('message');

const simpleFormat = format.simple();

const info = simpleFormat.transform({

level: 'info',

message: 'my message',

number: 123

});

console.log(info[MESSAGE]);

// info: my message {number:123}
  • timestamp 时间,接收一个[fecha]()库可以理解的字符串。

format.timestamp({

format: 'HH:mm:ss YY/MM/DD'

})
  • Uncolorize 去除颜色

自定义levels

winston定义了两种levels,默认用的是npm levels


{

error: 0,

warn: 1,

info: 2,

http: 3,

verbose: 4,

debug: 5,

silly: 6

}

当然支持自定义levels


const myCustomLevels = {

levels: {

foo: 0,

bar: 1,

baz: 2,

foobar: 3

},

colors: {

foo: 'blue',

bar: 'green',

baz: 'yellow',

foobar: 'red'

}

};

const customLevelLogger = winston.createLogger({

levels: myCustomLevels.levels

});

customLevelLogger.foobar('some foobar level-ed message');

多个传输

如果需要把成功级别的消息传入一个log文件,错误的传入另一个log文件,那么可以这么使用

由level针对级别。


const logger = winston.createLogger({

transports: [

new winston.transports.File({

filename: 'combined.log',

level: 'info'

}),

new winston.transports.File({

filename: 'errors.log',

level: 'error'

})

]

});

常见的transport

每个不同的transport都可以使用不同的format参数。毕竟要写入的格式与内容不同。


const logger = winston.createLogger({

transports: [

new winston.transports.File({

filename: 'error.log',

level: 'error',

format: winston.format.json()

}),

new transports.Http({

level: 'warn',

format: winston.format.json()

}),

new transports.Console({

level: 'info',

format: winston.format.combine(

winston.format.colorize(),

winston.format.simple()

)

})

]

});

异常处理

winston的异常处理。

Handling Uncaught Exceptions with winston

未捕获的异常,winston可以处理。


const logger = createLogger({

transports: [

new transports.File({ filename: 'combined.log' })

],

exceptionHandlers: [

new transports.File({ filename: 'exceptions.log' })

]

});

阅读更多

winston将异常保留在对应的log文件中后会退出

设置exitOnError: false,可以取消退出。

未捕获的promise

使用rejectionHandlers


const { createLogger, transports } = require('winston');

// Enable rejection handling when you create your logger.

const logger = createLogger({

transports: [

new transports.File({ filename: 'combined.log' })

],

rejectionHandlers: [

new transports.File({ filename: 'rejections.log' })

]

});

阅读更多

你可能感兴趣的