C# 中灵活的日志记录接口设计

2024-01-27

我想编写自己的日志记录类(用 C# 编写),它实现一个标准接口,我可以从代码的任何部分调用该接口。

我的想法是让多个 Log 类实现 Logger 接口,每个类都有其特定的日志目的地,例如,FileLogger 将实现记录到文件,TextBox 记录器将实现记录到表单中的多行 TextBox,DBLogger 将实现记录到文件实现日志记录到数据库表等。

此外,每个记录器类可以具有嵌套记录器或链式记录器类,以便从应用程序代码中对 Log() 方法的单次调用可以将消息记录到多个目的地;示例在一次调用中记录到表单上的文件和文本框。

我面临的困难是这样的:

通常我会记录到一个正在运行的日志文件(其中包含调试所需的所有日志消息)、一个审阅日志文件(其中仅包含要由用户审阅或需要用户操作的日志消息)、一个多行文本框屏幕(它将复制所有日志消息以向用户提供进度指示)和另一个多行文本框(它将仅记录用户查看所需的消息)。

当我调用 logger.Log(message) 时,某些消息可能不适用于特定日志目标。例如,某些消息可能旨在仅记录在运行日志文件或进度文本框中,而不记录在用户审阅文本框中,反之亦然。

由于记录器将被链接起来,以便单个函数调用可以登录到所有所需的目的地,因此特定记录器如何识别日志消息不是为它准备的,从而忽略该日志消息?

我的示例日志界面是:

public interface Logger
{
    public void Log(string msg);
    public void Log(string msgType, string msg);
    public void InitLogSession();
    public void EndLogSession();
    public void AddLogger(Logger chainedLogger);
    public void RemoveLogger(Logger chainedLogger);
}

public class FileLogger : Logger
{
      //implement methods
}

public class TextBoxLogger : Logger
{
      //implement methods
}

public class DBLogger : Logger
{
      //implement methods
}

EDIT 1:

更准确地说,可能有 4 个记录器:2 个文件记录器和 2 个文本框记录器。假设一条特定消息适用于 1 个文本框记录器和 1 个文件记录器;我的设计应该如何处理这个问题?

编辑2: 请不要建议现有的日志框架。我只想自己写!

编辑3: 好的。我有一个设计。请提供您的反馈并可能填补空白。

修改后的界面:

public interface Logger
{
    public void Log(string msg);
    public void Log(string msgType, string msg);
    public void Log(int loggerIds, string msg);
    public void Log(int loggerIds, string msgType, string msg);
    public void InitLogSession();
    public void EndLogSession();
    public int getLoggerId();
}

public enum LoggerType
{
    File,
    TextBox
};

public class LoggerFactory
{
    public Logger getLogger(LoggerType loggerType)
    {

    }
}

LoggerFactory 类将是实例化记录器的唯一方法。此类将为记录器的每个实例分配一个唯一的 ID。这个唯一的 id 将是 2 的幂。例如,第一个记录器将获得 id 1,第二个记录器将获得 id 2,第三个记录器将获得 4,第四个记录器将获得 8,依此类推。

返回的记录器对象可以类型转换为特定的类,并且调用者可以设置其他值,例如 filePath、文本框等,或者我可以在 LoggerFactory 中拥有多个方法:每种类型的记录器都有一个方法,它将接受特定的参数。

因此,假设我们有 4 个记录器,id 分别为 1,2,4,8。 必须使用以下函数记录必须由第一个和第三个记录器(即记录器 ID 1 和 4)处理的特定消息:

    public void Log(int loggerIds, string msg);

要传递给 loggerIds 的值应该是“0101”。每个记录器都会检查其记录器 ID 位是否为 ON。如果是,只有这样它才会记录该消息。

现在在函数签名中,我提到了 int 类型,但是执行位操作和比较的具体优化类型是什么?

在这种方法中,最大数量可能有限制。伐木工,但这对我来说很好。请提供您的反馈。

注意:目前我仍在使用.NET 2.0。如果可能的话,建议在 .NET 2.0 内提供解决方案,否则很好,我可以迁移到更高版本。

这种设计的缺点:每个需要记录的类都需要了解应用程序实例化的所有可用记录器,并相应地设置位模式。关于如何进行松散耦合设计有什么想法吗?


为什么你不看看(或者确实使用)现有的日志框架,例如log4net http://logging.apache.org/log4net/ or NLog http://nlog-project.org/.

它们具有日志级别的概念(例如跟踪、信息、错误等),并且能够按日志名称进行过滤(通常是调用日志记录调用的完全限定类型名称)。然后,您可以将这些映射到一个或多个“目标”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中灵活的日志记录接口设计 的相关文章

  • Dapper 强类型查询返回默认对象值

    刚刚开始使用 Dapper 并喜欢它 我遇到了问题 它返回正确数量的对象 但它们的属性都有默认值 using var dbConnection Connection await dbConnection OpenAsync const st
  • 如何使用 C# 打印 pdf

    我在 C 应用程序中使用 进程 打印 pdf 文件 但是我无法获取打印状态 我发现可以通过 System management 和 System printing 与打印机 队列进行交互 我做了很多尝试 但都出错了使用这两个命名空间但无法打
  • 在两个 .cpp 文件之间定义全局变量 [重复]

    这个问题在这里已经有答案了 如何在 A cpp 和 B cpp 之间共享 全球化 bool 变量 其中它们都不包含其他 h 文件 他们有其他联合头文件 但彼此没有 我可以在这些共享标头中定义全局变量吗 Thanks 我可以在这些共享标头中定
  • C#9 顶级语句文件上的属性

    我正在尝试向顶级语句文件添加属性 但没有找到任何相关信息 是否可以 对于某些上下文 我想仅在该文件中禁用规则 SuppressMessage StyleCop CSharp LayoutRules SA1516 ElementsMustBe
  • 实体框架中的重复键异常?

    我试图捕获当我将具有给定用户名的现有用户插入数据库时 引发的异常 正如标题所说 我正在使用 EF 当我尝试将用户插入数据库时 引发的唯一异常是 UpdateException 如何提取此异常以识别其是否是重复异常或其他异常 catch Up
  • 如何将 C++ 类包装在基于 C 的 dll 或基于 CLI 的 dll 中?

    我被告知将我用 C 编写的类导入到 dll 中 然后在 c 应用程序中使用该 dll 下列的本指南 https stackoverflow com questions 4555961 how to use a class in dll我创建
  • 此插件导致 Outlook 启动缓慢

    我正在使用 C NET 4 5 开发 Outlook Addin 项目 但部署后 有时 Outlook 会禁用我的插件 并显示此消息 这个插件导致 Outlook 启动缓慢 我不知道我的插件出了什么问题 这只有很少的代码 并且ThisAdd
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机
  • C++:获取注册表值仅给出第一个字符[重复]

    这个问题在这里已经有答案了 我试图从注册表中获取字符串值 但我只得到第一个字母 HKEY hKey char gamePath MAX PATH if RegOpenKeyEx HKEY CURRENT USER L Software Bl
  • 将语句插入 SQL Server 数据库

    最近几天我试图找到这个错误 但没有成功 我正在尝试在数据库中插入一个新行 一切都很顺利 没有错误 也没有程序崩溃 My INSERT声明如下 INSERT INTO Polozaj Znesek Uporabnik Cas Kupec Po
  • 当我尝试使用 AVX 功能时,Clang 生成错误

    我使用的是 Windows 10 使用 Clang 版本 5 最近安装 当我编译以下内容时 define AVX define AVX2 include
  • Windows 程序如何临时更改其时区?

    我写了一个函数来返回time t与给定日期的午夜相对应的值 当给定日期没有午夜时 它返回最早可用的时间 例如 当埃及进入夏令时时 这种情况就可能发生 今年 时间更改于 4 月 29 日晚上午夜生效 因此时钟直接从 23 59 转到 01 0
  • 首先EntityFramework数据库 - 类型映射 - 将binary(8)从SQL映射到C#中的int

    在 SQL 内部 我有一个主键为二进制 8 的表 当我使用该表添加到我的模型中时Update Model from Database我可以看到该列有 type Binary 在 C 中 我将该列设为byte 我可以将该列映射到 int 吗
  • 我们应该使用 Eval 还是 Databind 事件?

    当使用 Asp Net 并使用 ListView 等控件创建网站时 使用 Eval 命令是一个好习惯吗 还是应该在 databind 事件中填充文字和数据 取决于您是否想在更新事件上写回数据 在这种情况下数据绑定 如果您只想读取该数据 可以
  • 在 C++ 中处理音频缓冲区时,如何执行从 float -> double -> float 的转换

    我目前正在开发一个应用程序 其中音频样本帧在以下回调中进行处理 void Eav07AudioProcessor processBlock AudioSampleBuffer buffer for int channel 0 channel
  • ASP MVC 5 - 403 customError 不起作用

    我正在尝试为我的应用程序创建自定义错误页面 它在大部分情况下都有效 但不适用于403 errors 我的网络配置
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • 语义问题 Qt Creator:命名空间“std”中没有名为“cout”的成员

    我开始使用 Qt Creator 编写代码 对于 C 文件 我遇到很多语义问题 99 是 命名空间 yyy 中没有名为 xxx 的成员cpp文件构建 编译和输出没有问题 如果我点击例如cout 我已链接到 iostream 我是否需要在 Q
  • 计算两个日期之间的工作日数?

    在C 中 如何计算business 或工作日 两个日期之间的天数 我以前曾经遇到过这样的任务 并且我已经找到了解决方案 当可以避免的时候 我会避免列举其间的所有日子 这里就是这种情况 正如我在上面的一个答案中看到的那样 我什至没有提到创建一
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码

随机推荐

  • 创建热图时出错 - 外部函数调用中的 NA/NaN/Inf (arg 11)

    我正在尝试为我的数据准备热图 但我不知道为什么会出现此错误 My data gt dput head tbl ready structure c 0 0 0 0 0 0 0 0 0 0 0 0 0 0 370330677123077 0 0
  • Firebase Cloud Messaging (FCM) 如何切换 Apple 推送通知服务 (APN) 的环境?

    在 Apple 推送通知服务 APN 中 服务器端开发人员必须选择环境类型 沙箱或生产 作为 HTTP 2 URL api sandbox push apple com 或 api push apple com 1 https develo
  • jquery fullcalendar 事件过滤

    有没有什么方法可以在全日历中动态过滤客户端事件 当我从服务器 json encoded 获取事件时 我将自己的参数 school id 分配给每个事件 fullcalendar 准备好后 我想用 select 动态过滤事件 我在页面上添加
  • 升级 SonarQube 问题

    我在安装实例时遇到问题SonarQube4 4至5 1 The 指示 http docs sonarqube org display SONAR Upgrading比如说停止 SonarQube 服务器 匹配几个文件 备份数据库 复制插件等
  • React Hooks:在 Socket.io 处理程序内部调用时状态未更新

    const questionIndex setQuestionIndex useState 0 socket on next gt console log hey setQuestionIndex questionIndex 1 useEf
  • 使用 ptrace 解析 Call 和 Ret。

    我尝试使用 ptrace 解析可执行文件中的所有 Calls 和 Rets 符合x64操作码 http ref x86asm net coder64 html 我找到了操作码呼叫 0xe8并为重试 0xc3 0xc2 0xca 0xcb 自
  • Slurm 多处理 Python 作业

    我有一个 4 节点 Slurm 集群 每个节点有 6 个核心 我想提交一个利用多重处理的测试 Python 脚本 它会生成打印正在运行的节点的主机名的进程 如下所示 def print something print gethostname
  • 仅限水平滚动!

    我有一个包含水平菜单的菜单 菜单由无序列表组成 我希望每当菜单超出宽度时 div 都会获得水平滚动条 div 我尝试使用这些 CSS 定义 div position absolute width 380px overflow auto ov
  • 输入“用户|未定义”不可分配给类型“用户”

    用户控制器 import User from user export class UserController public static async getuser ctx BaseContext const userRepository
  • Safari 中的 CSS 过渡变换 z-index 冲突(适用于 Chrome / FF)

    我正在尝试使用 CSS 过渡和旋转效果来显示名片 我在 Chrome 和 FF 中一切正常 但在 Safari 中它扭曲了 div 我尝试应用以下属性但无济于事 transform translateZ 0px transform styl
  • d3 力定向图中的缩放和刷动

    我在执行缩放时让 D3 执行正确的刷牙时遇到问题 我在这里创建了一个 jsFiddlehttp jsfiddle net Gwp25 2 http jsfiddle net Gwp25 2 用我在其他地方找到的一些虚拟数据显示网络 接下来的
  • 以编程方式将音乐添加到 iOS

    假设我想创建一个从互联网下载音乐文件的 iOS 应用程序 那么是否可以将此音乐文件放在音乐库中以便我可以播放它 这是不可能的 将音乐添加到资料库的唯一方法是通过 iTunes 或 iTunes Store 应用程序 即使您确实找到了一种方法
  • 通过使用 React 按钮设置状态来循环遍历数组中的对象

    所以我有一些想要循环浏览的数据 const data names name Jordan additional data name Holly additional data name Sean additional data Using
  • 使用 PrintDocument 打印多页

    我正在尝试打印发票 发票应该能够在多页上打印 但这就是问题出现的地方 我可以在单页上完美地打印发票 但是一旦发票不适合在单页上打印 打印作业就会退出第一页 这是我正在使用的代码 artikelen 是文章列表 List 我读过几个类似的例子
  • 生产环境中的 Rails 服务器如何工作?

    我想知道 总的来说 它更像 PHP 它加载到内存中 执行 然后在每次连接时终止 或者像 Node js 单个实例保留在内存中并接受所有请求 从技术上讲是后者 但根据应用程序服务器 可以将其设置为look喜欢前者 因为前者更容易管理 Phus
  • 如何在 Dropwizard(泽西岛)中记录 JSON 响应

    我想知道如何配置 Dropwizard 来记录 JSON 响应 在 Service 子类 例如 HelloWorldService 的 run 方法中 添加 environment setJerseyProperty ResourceCon
  • pthread的调度方法?

    由于没有显式调度 pthread 被调度为由内核以随机方式运行 pthread 库中是否定义了相同的调度方法 例如优先级 线程的优先级被指定为增量 该增量被添加到进程的优先级上 更改进程的优先级会影响该进程中所有线程的优先级 线程的默认优先
  • 如何向 DetailDisclosureButton 添加标签文本?

    我正在使用 iOS Swift 2 0 应用程序 我一生都无法弄清楚如何将文本设置在右侧UITableViewCell就在披露指示符 V 形之前 除了创建自定义cell accessoryView 这是 设置应用程序 的屏幕截图 它正是我想
  • PHP 命令,未找到

    我尝试安装composer通过 PHP 命令 如 getcomposer 站点中所述 但 bash 抛出错误 bash php command not found 所以我在谷歌上搜索了一下 我得到了一些答案 1 添加php二进制文件路径 P
  • C# 中灵活的日志记录接口设计

    我想编写自己的日志记录类 用 C 编写 它实现一个标准接口 我可以从代码的任何部分调用该接口 我的想法是让多个 Log 类实现 Logger 接口 每个类都有其特定的日志目的地 例如 FileLogger 将实现记录到文件 TextBox