Log4jsでログ出力すると同時にSymbolブロックチェーンに記録する。

今日はログ出力すると同時に同じ内容をSymbolブロックチェーンに記録する方法を紹介します。


```js
const log4js = require('log4js');
const sym  = require("symbol-sdk");

const nodeURL = 'https://node.xembook.net';
const repositoryFactory = new sym.RepositoryFactoryHttp(nodeURL);
const transactionHttp = repositoryFactory.createTransactionRepository();

var networkType ;
var networkCurrency ;
var epochAdjustment ;
var generationHash ;
var alertAccount;

log4js.addLayout('symbol', function(config) {
    return function(logEvent) { 
        console.log(logEvent.data[0]);

        const tx = sym.TransferTransaction.create(
            sym.Deadline.create(epochAdjustment),
            alertAccount.address, 
            [],
            sym.PlainMessage.create(logEvent.data[0]),
            networkType
        ).setMaxFee(100);

        const signedTx = alertAccount.sign(tx, generationHash);
        return transactionHttp.announce(signedTx);
    }
});

log4js.configure({
  appenders: {
    file: { type: 'file', filename: 'logs/log4.log' ,maxLogSize:10000000,buckups:5},
    out: { type: 'stdout', layout: { type: 'symbol' } }
  },
  categories: {
    default: { appenders: ['out','file'], level: 'info' }
  }
});

const logger = log4js.getLogger();

(async () => {

    networkType = await repositoryFactory.getNetworkType().toPromise();
    networkCurrency = (await repositoryFactory.getCurrencies().toPromise()).currency;
    epochAdjustment = await repositoryFactory.getEpochAdjustment().toPromise();
    generationHash = await repositoryFactory.getGenerationHash().toPromise();

    alertAccount =  sym.Account.createFromPrivateKey("****************",networkType);
    console.log(alertAccount);

    logtest();
})();

function logtest(){
    logger.info('this is just a test');
}
```

# 解説

#### addLayout

Log4jsのaddLayoutという機能を使用します。

```js
log4js.addLayout('symbol', function(config) {
    return function(logEvent) { 
        console.log(logEvent.data[0]);

        const tx = sym.TransferTransaction.create(
            sym.Deadline.create(epochAdjustment),
            alertAccount.address, 
            [],
            sym.PlainMessage.create(logEvent.data[0]),
            networkType
        ).setMaxFee(100);

        const signedTx = alertAccount.sign(tx, generationHash);
        return transactionHttp.announce(signedTx);
    }
});
```
symbolというレイアウトが呼ばれたら、ログに指定されたメッセージをトランザクションとして送信します。


#### configure

設定は以下のようにしてみました。

```js
log4js.configure({
  appenders: {
    file: { type: 'file', filename: 'logs/log4.log' ,maxLogSize:10000000,buckups:5},
    out: { type: 'stdout', layout: { type: 'symbol' } }
  },
  categories: {
    default: { appenders: ['out','file'], level: 'info' }
  }
});
```
ファイル出力と標準出力の2つを行います。標準出力時にlayout:symbolを使うようにしました。

#### 初期設定

```js
(async () => {

    networkType = await repositoryFactory.getNetworkType().toPromise();
    networkCurrency = (await repositoryFactory.getCurrencies().toPromise()).currency;
    epochAdjustment = await repositoryFactory.getEpochAdjustment().toPromise();
    generationHash = await repositoryFactory.getGenerationHash().toPromise();

    alertAccount =  sym.Account.createFromPrivateKey("****************",networkType);
    console.log(alertAccount);

    logtest();
})();
```

ブロックチェーンに記録するために必要な情報を読み込んでおきます。

#### ログ出力

出力してみましょう

```js
logger.info('this is just a test');
```

ログファイルとブロックチェーンの両方に記録されましたでしょうか？



# さいごに

今回の検証の意味ですが、電子カルテや住民情報へのアクセス記録など消してはいけないログを残す必要がある場合や、公文書などの管理情報の更新履歴にブロックチェーンへの記録が有効活用されるのではないかと感じています。
今後、デジタル化が進み様々な情報が結合されるようになると、一つの情報に紐づいて様々な情報が芋づる式に抽出されてしまう可能性があります。自分の情報が誰にアクセスされたのか、改ざん不可として保管され文書が不適切に更新されていないか、そういった情報をシステムをほとんど変更せずに監査体制を強めることが可能になるかもしれません。