我正在开发一个 API,它会进行大量调用,其中一些由于各种原因需要彻底记录。
目前,我记录了函数中发生的所有输入/输出/处理,并且 API 运行完美,因此似乎没有必要增加日志记录量。
但一个让我印象深刻的想法是为每个传入的 API 调用分配一个 UUID,这将遵循内部函数中的日志记录。
虽然它会在每个函数中创建大量附加参数来跟随 UUID,但我想知道这是否是常见做法,我是否应该在需要出现之前实现它,而要做的更改量是易于管理。
例如:
显然真正的代码要复杂得多,并且不使用 console.log 进行日志记录
const express = require('express'),
fs = require('fs'),
config = require('./config.json'),
app = express();
function foo(bar, callback) {
console.log(bar);
fs.open(bar, (err, data) => {
if(err) {
console.err(err);
callback(err);
} else {
console.log(data)
callback(null, data);
}
});
}
app.get('/foo', (req, res) => {
console.log(req.body);
foo(req.body.bar, (err, result) => {
if(err) {
console.err(err);
res.send(err);
} else {
console.log(result)
res.send(null, result);
}
});
});
app.listen(config.port);
收件人:
const express = require('express'),
UUID = require('uuid-generator'),
fs = require('fs'),
config = require('./config.json'),
app = express();
function foo(uuid, bar, callback) {
console.log(uuid + ': ' + bar);
fs.open(bar, (err, data) => {
if(err) {
console.err(uuid + ': ' + err);
callback(err);
} else {
console.log(uuid + ': ' + data)
callback(null, data);
}
});
}
app.use((req, res, next) => {
req.id = new UUID();
next();
});
app.get('/foo', (req, res) => {
console.log(req.id + ': ' + req.body);
foo(req.id, req.body.bar, (err, result) => {
if(err) {
console.err(req.id + ': ' + err);
res.send(err);
} else {
console.log(req.id + ': ' + result)
res.send(null, result);
}
});
});
app.listen(config.port);
优点是,万一函数失败,或者系统崩溃,我们可以准确地确定是哪个调用导致了错误,以及更容易遵循哪条路径。
缺点是,它需要大量的工作来实现,并且可能没有那么有用,因为我们已经可以从不同的输入/输出和其他已经实现的日志记录中推断出遵循的路径。
TL:DR:以这种粒度级别记录每个请求是常见的做法,还是为特定用例保留?
是否有任何工具可以将其自动化,我不应该在代码中关心它?
最佳答案
我无法真正评论这是否是普遍做法,但在我最近开发的产品中,这是相当普遍的做法。
根据用例,我可以看到通过系统跟踪单个请求的很多值(value)。高流量 API 往往会从中受益,由微服务组成的系统也是如此,您可能需要通过多个连接服务来跟踪请求。
例如,如果您有一个接受需要存储的输入的 API,那么能够将特定输入数据与失败的数据库写入相关联会非常有用。
如果您决定要将 UUID 添加到您的请求中,那么 express-request-id中间件是一个有用的模块,它会为您生成一个 UUID 并将其添加到响应 header 中。如果出现在传入请求 header 中,它还可以采用 UUID 并使用它,这对于跟踪服务之间的请求很有用。
我还没有看到任何 Node 可以完全抽象记录各个请求,但我没有寻找过。
关于javascript - 日志记录会要求单独的良好实践还是杂乱无章?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39856975/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).
我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS
我认为我的问题最好用一个例子来描述。假设我有一个名为“Thing”的简单模型,它有一些简单数据类型的属性。像...Thing-foo:string-goo:string-bar:int这并不难。数据库表将包含具有这三个属性的三列,我可以使用@thing.foo或@thing.bar之类的东西访问它们。但我要解决的问题是当“foo”或“goo”不再包含在简单数据类型中时会发生什么?假设foo和goo代表相同类型的对象。也就是说,它们都是“Whazit”的实例,只是数据不同。所以现在事情可能看起来像这样......Thing-bar:int但是现在有一个新的模型叫做“Whazit”,看起来
我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame
我有一个要在我的Rails3项目中使用的数组扩展方法。它应该住在哪里?我有一个应用程序/类,我最初把它放在(array_extensions.rb)中,在我的config/application.rb中我加载路径:config.autoload_paths+=%W(#{Rails.root}/应用程序/类)。但是,当我转到railsconsole时,未加载扩展。是否有一个预定义的位置可以放置我的Rails3扩展方法?或者,一种预先定义的方式来添加它们?我知道Rails有自己的数组扩展方法。我应该将我的添加到active_support/core_ext/array/conversion
我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr