我想在我的应用程序中添加一个日志。我选择了一个日志记录库,但我希望能够切换到另一个库,而不必更改任何使用日志记录的代码。
因此,我需要某种足够灵活的日志包装器,以利用几乎所有底层日志库的功能。
对于这种包装器的设计有什么建议吗?
编辑:我必须在这个包装器中拥有的一个功能是组件标记。我希望我的算法类在其日志行之前显示“X:”,而我的管理器类在其日志行之前显示“Y:”。如何将这些标签传播到底层日志以及如何构建组件标签命名机制是这里的一个主要设计问题。
最佳答案
最好的办法是使界面尽可能简单。将日志记录用户界面与日志记录的实际实现方式完全分开。
横切关注点的维护成本总是很高的,所以让事情变得更复杂会让你讨厌生活。
有些图书馆只想要像这样简单的东西:
void logDebug(const std::string &msg);
void logWarning(const std::string &msg);
void logError(const std::string &msg);
他们不应添加或指定任何更多上下文。反正没有人可以使用这些信息,所以不要过度设计它。
如果您开始向日志记录调用添加更多信息,那么重用使用它的客户端代码就会变得更加困难。当在不同的抽象级别使用组件时,您通常会看到这个表面。特别是当一些低级代码提供仅与更高级别相关的调试信息时。
这不会强制您的日志记录实现(甚至日志记录实现所遵循的接口(interface)!)变成任何东西,因此您可以随时更改它。
更新:
就标记而言,这是一个高级别问题。我打算推测它不属于日志,但它既不在这里也不在那里。
将其排除在日志消息规范之外。低级代码不应该让飞行卡车知道你或你的经理是谁。
我不知道您如何在示例中指定 X 或 Y。从我们给出的描述中,您如何做到这一点并不是很明显。我将只使用字符串进行演示,但如果可能的话,您应该将其替换为类型安全的内容。
如果它总是打开,那么只需要一个实例上下文(可能是一个全局变量)可能是合适的。当您登录时,设置上下文并忘记它。如果未设置,请以极端偏见 throw 。如果在未设置时无法抛出,则说明它未始终开启。
void setLoggingContext("X:");
如果这在不同的抽象级别发生变化,我会考虑基于堆栈的 RAII 实现。
LoggingTag tag("X:");
当不同的栈帧传入不同的值时,我不确定你的需求是什么。对于不同的用例,我可以看到堆栈的顶部或底部在哪里是合理的。
void foo() {
LoggingTag tag("X:");
logWarning("foo");
bar();
baz();
}
void bar() {
LoggingTag tag("Y:");
logWarning("bar");
baz();
}
void baz() {
logWarning("baz");
}
无论哪种方式,这都不应该影响您将消息添加到日志的方式。 baz 函数没有上下文来指定 LoggingTag。由于这个原因,使用 logWarning 并不知道标签是非常重要的。
如果你想基于某种类型进行标记,你可以像这样做一些简单的事情。
struct LoggingTag {
LoggingTag(const std::string &tag_) : tag(tag_) {}
template<typename T>
static LoggingTag ByType() {
return LoggingTag(typeid(T).name());
}
std::string tag;
};
void foo() {
LoggingTag tag = LogginTag::ByType<int>();
}
这不会强制某人使用typeid(T).name(),如果他们不想的话,但给了你方便。
关于C++ 日志包装器设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7892810/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“