记录具有保存敏感数据的属性的对象

问题描述 投票:2回答:1

上下文

我正在设计应用程序的日志记录功能。寻找一种优雅且性能优良的解决方案。(当然,我不会重新设计轮子:)。我将使用流行的日志记录库-例如Nlog,Serilog ...)。

要求

处理包含some属性的对象日志,这些属性包含敏感信息。让我们假设一个班级的人:

class Person {
    string Name { get; set; }
    string SensitiveInfo { get; set; }
}

一种不好的(在我看来)的方法是做这样的事情:

logger.Debug($"{person.Name}, {Hash(person.SenstiveInfo)}");

为什么我觉得这个不好?

  1. 这是调试日志,它可能从未记录过(基于记录级别)。因此,它浪费了CPU资源,无需任何哈希。
  2. 我希望允许按原样记录对象(例如logger.Debug(person),而不是强迫开发人员手动分解所有对象属性。

到目前为止的想法...

以下两种方法都需要loggerWrapper-如果可能,我想避免:

class LoggerWrapper {
    LoggerWrapper (ILogger logger) {
        //store the ILogger
    }
    void Log(object objectToBeLogged, LoggingLevel level) {
        //If logging level is not accepted return
        _logger.Log(objectToBeLogged, level);
    }
}

1。创建一个ILoggable接口

interface ILoggable {
    string GetLogValue(HashManager hashManager);
}

class Person: ILoggable {
    string Name { get; set; }
    string SensitiveInfo { get; set; }

    string GetLogValue(HashManager hashManager) {
        string hashedValue = hashManager.Hash(person.SenstiveInfo);
        return $"{person.Name}, {hashedValue}"
    }
}

// Now the logWrapper will accept an ILoggable, and will handle it accordingly
// overriding 'ToString()' is an alternative but it is exposed by the 'object' class, and i fear that is not strict enough/can be forgotten.

对此方法的担忧:对开发人员的要求过高吗?可维护性?

2。注释和反射

class Person {
    [Loggable]
    string Name { get; set; }
    [Loggable, SensitiveInfo]
    string SensitiveInfo { get; set; }
}

// Now the logWrapper will rely on reflection (i think) and choose what to log/hash

与这种方法有关:性能?


以上方法是否被视为不良做法?有没有更好的方法?是否有任何已经在处理此问题的库?

c# .net logging .net-4.0 log4net
1个回答
0
投票

您的第二方法是可以的。

我可以想到几种替代方法,但是最终它们将与属性批注非常接近。-像在外部文件中保留某种注释信息。-或创建像'SensitiveInfo<T>'这样的特殊类型,并在必须进行哈希处理的地方使用它,但与注释属性几乎相同。

对于演奏部分:您可以在应用程序的开头创建一个时间结构,以扫描程序集中的所有类型。该结构可以是具有类型名称作为键("MyCompany.App.Core.Person")的字典,对于键,您可以具有从Func创建的Func对象,该对象将在需要时返回带有散列值的日志消息。 (这将是困难的部分)。重要提示:jit编译器直到需要时才加载dll,因此在初次启动时尝试创建此结构可能会跳过某些程序集。作为替代方法,您可以尝试在记录器包装程序中填充按需结构(惰性)。

然后,我将使用日志记录包装器,它将使用该结构为特定对象创建日志记录消息。

一些建议:1.记录太多信息并不一定是一件坏事-因此我不会使用[dynamically compiled lambda expression]属性-只需记录对象中的所有内容即可。这样,开发人员的开销将最小化。有时您的对象中可能有很长的字符串,这些字符串并不重要,然后可以引入[Loggable]属性。2.您可能将要处理层次结构对象-这将增加创建func / labbda表达式的复杂性。

总体而言,这种方法较为复杂,但对开发人员的要求却较低。最后,这取决于您和您的团队愿意做什么以及将花费/保存的工作量(这取决于项目的大小..等)。


我认为第一种方法将变得难以维护,并且会增加很多噪音。日志记录应该是基础架构关注的问题-尽可能自动化。

© www.soinside.com 2019 - 2024. All rights reserved.