リクエストオブジェクトの破棄を制御するためのオプション

マシュトン

私はクリーンな解決策を見つけるのに苦労している問題に遭遇しました、そしてグーグルは私を賢くしませんでした。

状況

(1)Serilogロガーを設定してプロジェクト(一貫性のあるロギング出力、テーマなど)に追加するための独自のアセンブリがあり、このアセンブリには、(異なるリポジトリにある)消費プロジェクトへの参照がありません。これをCompanySerilogアセンブリと呼びましょう

(2)消費するプロジェクトの1つは、外部からアクセス可能なAPIであり、「contract」オブジェクトはExternalContractsアセンブリで定義されます。つまり、リクエストオブジェクトとレスポンスオブジェクト、およびそれらのオブジェクトの一部として使用される列挙型。このExternalContractsアセンブリは、APIに対して統合する開発者に提供できます。

(3)すべてのリクエストをログに記録し、を使用しIActionFilterて、Serilog構造化ログアプローチを使用して各リクエストオブジェクトをログアウトします。たとえば、コンテキスト内の各パラメータをループし、最終的に_logger.LogDebug("With {name} of {@requestObject}", name, value);

問題

一部のリクエストオブジェクトには、マスクしたい機密データがありますが、次のようになります。

  • CompanySerilog標準の.Destructure拡張機能を使用してロガーを作成するときに分解の方法を定義することはできますが、リクエストオブジェクトの詳細がわからない、または知りたい場合はApi1からのものである可能性があります。Api2これは、すべてに参照を追加することを意味しますプロジェクトを消費します。
  • リクエストオブジェクト(Destructurama.Attributed)に属性を追加することもできますが、そのExternalContracts場合、アセンブリにはそのNuGetパッケージへの参照が必要になり、必要なすべてのSerilogパッケージへの参照が必要になります。厳密に言えば、ExternalContractsアセンブリではロギングの懸念は必要ありません。これは、APIのコンシューマーではなく、私たちの問題です。

私が言っているように、私はこれを解決する方法を考え出すのに苦労していて、たとえばIDestructuringPolicyの使用に関する情報や、それが適切かどうか、または変換を実行する必要があるかどうかについての情報を見つけることができません。これまでのところ、私は次のオプションしか考えられませんが、他の誰かがこの問題に遭遇し、このユースケースをサポートするためのひどく賢くてクリーンな方法を持っていることを願っています。

ソリューション?

  • 構造化ロギングの実行を停止しToString()、ログに記録したくない値をマスクするリクエストオブジェクトごとにを定義するだけです。これは単純で、厄介なプロジェクトの相互参照や外部契約へのロギングの懸念の追加を必要としません。しかし、それは構造化ロギングが不可能であることを意味します。

  • 必要なすべてのロギング参照を外部コントラクトに追加します。これにより、組み込みの破棄を引き続き使用できますが、APIのコンシューマーは、ロギングアセンブリを含むExternalContractsアセンブリを使用することになります。

  • このアセンブリを使用するすべてのプロジェクトを参照して.Destructure、ログインを構成するときに値を設定しますCompanySerilog起こらない!

  • 他に何かありますか?お願いします!

マシュトン

誰かが同様の問題に遭遇した場合に備えて、2つの解決策を考え出しましたIDestructuringPolicyどちらもを使用する必要があります。

解決策1

アセンブリに単一のジェネリックIDestructuringPolicyがありCompanySerilogます。

public class SensitiveDataDestructuringPolicy : IDestructuringPolicy
    {
        public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
        {
            var props = value.GetType().GetTypeInfo().DeclaredProperties;
            var logEventProperties = new List<LogEventProperty>();

            foreach (var propertyInfo in props)
            {
                switch (propertyInfo.Name.ToLower())
                {
                    case "cardnumber":
                    case "password":
                        logEventProperties.Add(new LogEventProperty(propertyInfo.Name,propertyValueFactory.CreatePropertyValue("***")));
                        break;
                    default:
                        logEventProperties.Add(new LogEventProperty(propertyInfo.Name, propertyValueFactory.CreatePropertyValue(propertyInfo.GetValue(value))));
                        break;
                }

            }
            result = new StructureValue(logEventProperties);
            return true;
        }
    }

また、ロガーを設定するときは、次の種類の構成を使用します。

var logger = new LoggerConfiguration()
// snipped out all the other things that need configuring
// ...
.Destructure.With<SensitiveDataDestructuringPolicy>
.CreateLogger();

このアプローチの長所:

  • オブジェクトがどのタイプになるかを知らなくても、オブジェクトをログに記録する方法を決定する責任がある1つの場所(ロギングアセンブリ内)

このアプローチの短所:

  • これは、すべてのオブジェクトのすべてのプロパティに反映されます。これは、マスクする必要のあるオブジェクトが1つまたは2つしかない場合はやり過ぎです。

結局、最初のソリューションの短所のために、別のアプローチを採用しました。

解決策2

CompanySerilogロガーを作成するメソッドに、それを使用しているアセンブリでIDestructuringPoliciesを検索させます。

public static ILogger Create()
{
    var destructuringPolicies = GetAllDestructuringPolicies();

    var logger = new LoggerConfiguration()
    // snipped out all the other things that need configuring
    // ...
    .Destructure.With(destructuringPolicies)
    .CreateLogger();

    //Set the static instance of Serilog.Log with the same config
    Log.Logger = logger;

    logger.Debug($"Found {destructuringPolicies.Length} destructuring policies");
    return logger;
}

/// <summary>
/// Finds all classes that implement IDestructuringPolicy, in the assembly that is calling this 
/// </summary>
/// <returns></returns>
private static IDestructuringPolicy[] GetAllDestructuringPolicies()
{
    var policies = Assembly.GetEntryAssembly().GetTypes().Where(x => typeof(IDestructuringPolicy).IsAssignableFrom(x));
    var instances = policies.Select(x => (IDestructuringPolicy)Activator.CreateInstance(x));
    return instances.ToArray();
}

これで、このCompanySerilogアセンブリのコンシューマーは、IDestructuringPolicy関心のあるすべてのクラスに対してを定義することにより、機密データをログに記録する方法を定義する責任があります例えば:

public class RegisterNewUserDestructuringPolicy : IDestructuringPolicy
{
    public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
    {
        var request = value as RegisterNewUserRequest;
        if (request == null)
        {
            result = null;
            return false;
        }

        var logEventProperties = new List<LogEventProperty>
            {
                new LogEventProperty(nameof(request.Claims), propertyValueFactory.CreatePropertyValue(request.Claims)),
                new LogEventProperty(nameof(request.Email), propertyValueFactory.CreatePropertyValue(request.Email)),
                new LogEventProperty(nameof(request.Password), propertyValueFactory.CreatePropertyValue("****")),
                new LogEventProperty(nameof(request.Roles), propertyValueFactory.CreatePropertyValue(request.Roles)),
                new LogEventProperty(nameof(request.UserName),
                    propertyValueFactory.CreatePropertyValue(request.UserName))
            };

        result = new StructureValue(logEventProperties);
        return true;
    }
}

ソリューション1に対するこのアプローチの利点は、現在具体的なタイプを扱っていることです。そのタイプにポリシーがない場合、それは反映されません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

スプリングブートで使用するたびにBeanオブジェクトの状態を破棄またはクリアする方法

分類Dev

Scalaでオブジェクトのリストを作成するためのオプションのリストを含むリストの圧縮

分類Dev

ヒープオブジェクトを自動破棄するためのマクロ

分類Dev

IDisposableオブジェクトは、RequestContainerを使用したナンシーリクエストの最後に破棄されますか?

分類Dev

HighChartsのエクスポートオプションを制御する

分類Dev

アプリケーションを終了するときにオブジェクトを破棄するのはなぜですか?

分類Dev

Inno SetupPascalスクリプトでオブジェクトを破棄する

分類Dev

シェル スクリプトでバックグラウンド ジョブの数を制御する方法

分類Dev

別のクラスのオブジェクトを破棄する方法

分類Dev

カスタムキーによるMongoDBクエリコレクションと制限付きのネストされたオブジェクトを返す

分類Dev

UMLシーケンス図:条件付きのオブジェクトを破棄する

分類Dev

オブジェクトを破棄するときのStackOverflowException

分類Dev

文字列のコレクションから結合されたオブジェクトのコレクションを作成するためのLINQクエリ

分類Dev

既存のオブジェクトにデータを入力するためのJavascriptの破棄

分類Dev

For ... Inループはオブジェクトを作成するための唯一のオプションですか?

分類Dev

内部オブジェクトを取得するためにjavascriptオブジェクトを破棄する

分類Dev

新しいオブジェクトを構築するための代入の破棄-それは可能ですか?

分類Dev

オブジェクトのオプションのプロパティにアクセスするためのブラケット表記を使用したTypescript

分類Dev

オブジェクトのリストをJavaのオプションのオブジェクトのリストに変換する

分類Dev

尖った 2 つのオブジェクトを破棄する

分類Dev

JSONオブジェクトをループするためのJavaScript / jQueryソリューション

分類Dev

ループ内のオブジェクトを作成および破棄する

分類Dev

ネストされたオブジェクトの破棄

分類Dev

ネストされたオブジェクトの破棄

分類Dev

ネストされたオブジェクトの破棄

分類Dev

ネストされたオブジェクトの破棄:親とその子の値を取得する方法は?

分類Dev

ネストされたオプションのレルムオブジェクトをすばやくクエリする最も簡単な方法

分類Dev

オブジェクトのリストを破棄する方法;メモリを解放しますか

分類Dev

抽象オブジェクトのコレクション内のオブジェクトを更新するためのクリーンな方法

Related 関連記事

  1. 1

    スプリングブートで使用するたびにBeanオブジェクトの状態を破棄またはクリアする方法

  2. 2

    Scalaでオブジェクトのリストを作成するためのオプションのリストを含むリストの圧縮

  3. 3

    ヒープオブジェクトを自動破棄するためのマクロ

  4. 4

    IDisposableオブジェクトは、RequestContainerを使用したナンシーリクエストの最後に破棄されますか?

  5. 5

    HighChartsのエクスポートオプションを制御する

  6. 6

    アプリケーションを終了するときにオブジェクトを破棄するのはなぜですか?

  7. 7

    Inno SetupPascalスクリプトでオブジェクトを破棄する

  8. 8

    シェル スクリプトでバックグラウンド ジョブの数を制御する方法

  9. 9

    別のクラスのオブジェクトを破棄する方法

  10. 10

    カスタムキーによるMongoDBクエリコレクションと制限付きのネストされたオブジェクトを返す

  11. 11

    UMLシーケンス図:条件付きのオブジェクトを破棄する

  12. 12

    オブジェクトを破棄するときのStackOverflowException

  13. 13

    文字列のコレクションから結合されたオブジェクトのコレクションを作成するためのLINQクエリ

  14. 14

    既存のオブジェクトにデータを入力するためのJavascriptの破棄

  15. 15

    For ... Inループはオブジェクトを作成するための唯一のオプションですか?

  16. 16

    内部オブジェクトを取得するためにjavascriptオブジェクトを破棄する

  17. 17

    新しいオブジェクトを構築するための代入の破棄-それは可能ですか?

  18. 18

    オブジェクトのオプションのプロパティにアクセスするためのブラケット表記を使用したTypescript

  19. 19

    オブジェクトのリストをJavaのオプションのオブジェクトのリストに変換する

  20. 20

    尖った 2 つのオブジェクトを破棄する

  21. 21

    JSONオブジェクトをループするためのJavaScript / jQueryソリューション

  22. 22

    ループ内のオブジェクトを作成および破棄する

  23. 23

    ネストされたオブジェクトの破棄

  24. 24

    ネストされたオブジェクトの破棄

  25. 25

    ネストされたオブジェクトの破棄

  26. 26

    ネストされたオブジェクトの破棄:親とその子の値を取得する方法は?

  27. 27

    ネストされたオプションのレルムオブジェクトをすばやくクエリする最も簡単な方法

  28. 28

    オブジェクトのリストを破棄する方法;メモリを解放しますか

  29. 29

    抽象オブジェクトのコレクション内のオブジェクトを更新するためのクリーンな方法

ホットタグ

アーカイブ