apeescape2.com
  • メイン
  • その他
  • ツールとチュートリアル
  • アジャイル
  • 革新
技術

ELKからAWSへ:手間をかけずにログを管理する

Elasticsearchは、広範囲のデータ内の情報をすばやく検索するように設計された強力なソフトウェアソリューションです。 LogstashおよびKibanaと組み合わせると、これは非公式に名前が付けられたものになります 「任意のスタック」 、およびログデータの収集、一時的な保存、分析、および視覚化によく使用されます。通常、他のいくつかのソフトウェアが必要です。 Filebeat サーバーからLogstashにログを送信し、 Elastalert Elasticsearchに保存されているデータに対して実行された分析の結果に基づいてアラートを生成します。

ELKスタックは強力ですが…

ログの管理にELKを使用した私の経験はかなり複雑です。一方で、それは非常に強力であり、その機能の範囲は非常に印象的です。一方、設定は難しく、維持するのが頭痛の種になる可能性があります。

事実、Elasticsearchは一般的に非常に優れており、さまざまなシナリオで使用できます。検索エンジンとしても使えます!ログデータの管理に特化していないため、このようなデータを管理する特定のニーズに合わせて動作をカスタマイズするには、より多くの構成作業が必要になります。



ELKクラスターのセットアップは非常にトリッキーで、最終的に起動して実行するために、いくつかのパラメーターを試してみる必要がありました。次に、それを構成する作業が行われました。私の場合、構成するソフトウェアは5つありました(Filebeat、Logstash、Elasticsearch、Kibana、Elastalert)。ドキュメントを読み、次の要素と通信しないチェーンの1つの要素をデバッグする必要があったため、これは非常に面倒な作業になる可能性があります。最終的にクラスターを起動して実行した後でも、パッチの適用、OSパッケージのアップグレード、CPU、RAM、ディスクの使用状況の確認、必要に応じた微調整など、クラスターの定期的なメンテナンス操作を実行する必要があります。

Logstashの更新後、ELKスタック全体が機能しなくなりました。よく調べてみると、何らかの理由で、ELK開発者は設定ファイルのキーワードを変更して複数形にすることにしました。それが最後の藁であり、より良い解決策を探すことにしました(少なくとも私の特定のニーズのためのより良い解決策)。

ApacheとさまざまなPHPおよびノー​​ドアプリによって生成されたログを保存し、それらを解析してソフトウェアのバグを示すパターンを見つけたいと思いました。私が見つけた解決策は次のとおりです。

  • CloudWatchAgentをターゲットにインストールします。
  • ログをCloudWatchログに送信するようにCloudWatchAgentを設定します。
  • Lambda関数の呼び出しをトリガーして、ログを処理します。
  • パターンが見つかった場合、Lambda関数はSlackチャネルにメッセージを投稿します。
  • 可能な場合は、CloudWatchロググループにフィルターを適用して、すべてのログに対してLambda関数を呼び出さないようにします(これにより、コストが非常に急速に上昇する可能性があります)。

そして、大まかに言えば、それだけです!メンテナンスを必要とせずに正常に動作し、追加の作業なしで適切に拡張できる100%サーバーレスソリューション。サーバーのクラスターに対するこのようなサーバーレスソリューションの利点は数多くあります。

あなた自身のプライベートエクイティファンドを始める方法
  • 本質的に、クラスターサーバーで定期的に実行するすべての定期的なメンテナンス操作は、クラウドプロバイダーの責任になります。基盤となるサーバーには、知らないうちにパッチが適用され、アップグレードされ、保守されます。
  • クラスタを監視する必要がなくなり、すべてのスケーリングの問題をクラウドプロバイダーに委任します。実際、上記のようなサーバーレスセットアップは、何もしなくても自動的にスケーリングされます。
  • 上記のソリューションでは、必要な構成が少なくて済み、クラウドプロバイダーによって重大な変更が構成形式に反映される可能性はほとんどありません。
  • 最後に、CloudFormationテンプレートを作成して、それらすべてをInfrastructure-as-Codeとして配置するのは非常に簡単です。 ELKクラスター全体をセットアップするために同じことを行うと、多くの作業が必要になります。

Slackアラートの構成

それでは、詳細を見ていきましょう。エンジニアに警告するためのSlackWebhookを備えた、このようなセットアップでCloudFormationテンプレートがどのように表示されるかを見てみましょう。最初にすべてのSlackセットアップを構成する必要があるので、詳しく見ていきましょう。

AWSTemplateFormatVersion: 2010-09-09 Description: Setup log processing Parameters: SlackWebhookHost: Type: String Description: Host name for Slack web hooks Default: hooks.slack.com SlackWebhookPath: Type: String Description: Path part of the Slack webhook URL Default: /services/YOUR/SLACK/WEBHOOK

このためにSlackワークスペースを設定する必要があります。チェックアウトしてください このWebHooksforSlackガイド 追加情報については。

Slackアプリを作成し、着信フックを構成すると、フックURLがCloudFormationスタックのパラメーターになります。

Resources: ApacheAccessLogGroup: Type: AWS::Logs::LogGroup Properties: RetentionInDays: 100 # Or whatever is good for you ApacheErrorLogGroup: Type: AWS::Logs::LogGroup Properties: RetentionInDays: 100 # Or whatever is good for you

ここでは、2つのロググループを作成しました。 Apacheアクセスログ 、他の Apacheエラーログ 。

この記事の範囲外であるため、ログデータのライフサイクルメカニズムを構成しませんでした。実際には、保持期間を短くし、S3ライフサイクルポリシーを設計して、一定期間後にそれらをGlacierに移動することをお勧めします。

アクセスログを処理するLambda関数

それでは、Apacheアクセスログを処理するLambda関数を実装しましょう。

BasicLambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

ここでは、Lambda関数にアタッチされて職務を実行できるようにするIAMロールを作成しました。事実上、AWSLambdaBasicExecutionRole (その名前にもかかわらず)AWSによって提供されるIAMポリシーです。 Lambda関数がロググループとそのグループ内のログストリームを作成し、独自のログをCloudWatchLogsに送信できるようにするだけです。

ProcessApacheAccessLogFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt BasicLambdaExecutionRole.Arn Runtime: python3.7 Timeout: 10 Environment: Variables: SLACK_WEBHOOK_HOST: !Ref SlackWebHookHost SLACK_WEBHOOK_PATH: !Ref SlackWebHookPath Code: ZipFile: | import base64 import gzip import json import os from http.client import HTTPSConnection def handler(event, context): tmp = event['awslogs']['data'] # `awslogs.data` is base64-encoded gzip'ed JSON tmp = base64.b64decode(tmp) tmp = gzip.decompress(tmp) tmp = json.loads(tmp) events = tmp['logEvents'] for event in events: raw_log = event['message'] log = json.loads(raw_log) if log['status'][0] == '5': # This is a 5XX status code print(f'Received an Apache access log with a 5XX status code: {raw_log}') slack_host = os.getenv('SLACK_WEBHOOK_HOST') slack_path = os.getenv('SLACK_WEBHOOK_PATH') print(f'Sending Slack post to: host={slack_host}, path={slack_path}, url={url}, content={raw_log}') cnx = HTTPSConnection(slack_host, timeout=5) cnx.request('POST', slack_path, json.dumps({'text': raw_log})) # It's important to read the response; if the cnx is closed too quickly, Slack might not post the msg resp = cnx.getresponse() resp_content = resp.read() resp_code = resp.status assert resp_code == 200

したがって、ここでは、Apacheアクセスログを処理するためのLambda関数を定義しています。 Apacheのデフォルトである一般的なログ形式を使用していないことに注意してください。アクセスログの形式をそのように構成しました(基本的にJSONとして形式化されたログが生成されるため、処理がはるかに簡単になります)。

LogFormat '{'vhost': '%v:%p', 'client': '%a', 'user': '%u', 'timestamp': '%{%Y-%m-%dT%H:%M:%S}t', 'request': '%r', 'status': '%>s', 'size': '%O', 'referer': '%{Referer}i', 'useragent': '%{User-Agent}i'}' json

このLambda関数はPython3で記述されています。CloudWatchから送信されたログ行を受け取り、パターンを検索できます。上記の例では、5XXステータスコードを生成したHTTPリクエストを検出し、Slackチャネルにメッセージを投稿します。

パターン検出に関しては何でもできます。LogstashまたはElastalert構成ファイルの正規表現パターンではなく、真のプログラミング言語(Python)であるという事実により、複雑なパターン認識を実装する多くの機会が得られます。 。

リビジョン管理

リビジョン管理について簡単に説明します。このような小さなユーティリティLambda関数のCloudFormationテンプレートにコードをインライン化することは、非常に受け入れられやすく便利であることがわかりました。もちろん、多くのLambda関数とレイヤーを含む大規模なプロジェクトの場合、これはおそらく不便であり、SAMを使用する必要があります。

ApacheAccessLogFunctionPermission: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref ProcessApacheAccessLogFunction Action: lambda:InvokeFunction Principal: logs.amazonaws.com SourceArn: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*

上記は、CloudWatchLogsにLambda関数を呼び出す権限を与えています。注意の一言:SourceAccountを使用していることがわかりましたプロパティは、SourceArnとの競合につながる可能性があります。

一般的に言って、Lambda関数を呼び出しているサービスが同じAWSアカウントにある場合は、これを含めないことをお勧めします。 SourceArnとにかく、他のアカウントがLambda関数を呼び出すことを禁止します。

ApacheAccessLogSubscriptionFilter: Type: AWS::Logs::SubscriptionFilter DependsOn: ApacheAccessLogFunctionPermission Properties: LogGroupName: !Ref ApacheAccessLogGroup DestinationArn: !GetAtt ProcessApacheAccessLogFunction.Arn FilterPattern: '{$.status = 5*}'

サブスクリプションフィルターリソースは、CloudWatchLogsとLambdaの間のリンクです。ここでは、ApacheAccessLogGroupに送信されたログ上で定義したLambda関数に転送されますが、フィルターパターンを通過するログのみが転送されます。ここで、フィルターパターンは入力としてJSONを想定しており(フィルターパターンは「{」で始まり「}」で終わります)、フィールドstatusがある場合にのみログエントリと一致します。 「5」で始まります。

これは、Apacheによって返されるHTTPステータスコードが500コードである場合にのみ、Lambda関数を呼び出すことを意味します。これは通常、非常に悪いことが起こっていることを意味します。これにより、Lambda関数を呼び出しすぎないようにし、不要なコストを回避できます。

フィルタパターンの詳細については、をご覧ください。 AmazonCloudWatchのドキュメント 。 CloudWatchのフィルターパターンは非常に優れていますが、Grokほど強力ではありません。

DependsOnに注意してくださいフィールド。サブスクリプションが作成される前に、CloudWatchLogsが実際にLambda関数を呼び出すことができるようにします。これは単なるお菓子です。実際のシナリオのように、Apacheはおそらく少なくとも数秒前にリクエストを受信しないでしょう(例:EC2インスタンスをロードバランサーにリンクして負荷を取得するため)。 EC2インスタンスのステータスを正常であると認識するバランサー)。

エラーログを処理するLambda関数

それでは、Apacheエラーログを処理するLambda関数を見てみましょう。

ProcessApacheErrorLogFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt BasicLambdaExecutionRole.Arn Runtime: python3.7 Timeout: 10 Environment: Variables: SLACK_WEBHOOK_HOST: !Ref SlackWebHookHost SLACK_WEBHOOK_PATH: !Ref SlackWebHookPath Code: ZipFile: | import base64 import gzip import json import os from http.client import HTTPSConnection def handler(event, context): tmp = event['awslogs']['data'] # `awslogs.data` is base64-encoded gzip'ed JSON tmp = base64.b64decode(tmp) tmp = gzip.decompress(tmp) tmp = json.loads(tmp) events = tmp['logEvents'] for event in events: raw_log = event['message'] log = json.loads(raw_log) if log['level'] in ['error', 'crit', 'alert', 'emerg']: # This is a serious error message msg = log['msg'] if msg.startswith('PHP Notice') or msg.startswith('PHP Warning'): print(f'Ignoring PHP notices and warnings: {raw_log}') else: print(f'Received a serious Apache error log: {raw_log}') slack_host = os.getenv('SLACK_WEBHOOK_HOST') slack_path = os.getenv('SLACK_WEBHOOK_PATH') print(f'Sending Slack post to: host={slack_host}, path={slack_path}, url={url}, content={raw_log}') cnx = HTTPSConnection(slack_host, timeout=5) cnx.request('POST', slack_path, json.dumps({'text': raw_log})) # It's important to read the response; if the cnx is closed too quickly, Slack might not post the msg resp = cnx.getresponse() resp_content = resp.read() resp_code = resp.status assert resp_code == 200

この2番目のLambda関数は、Apacheエラーログを処理し、重大なエラーが発生した場合にのみSlackにメッセージを投稿します。この場合、PHPの通知および警告メッセージは、アラートをトリガーするほど深刻であるとは見なされません。

この場合も、この関数はApacheエラーログがJSON形式であることを想定しています。だからここに私が使っているエラーログフォーマット文字列があります:

ErrorLogFormat '{'vhost': '%v', 'timestamp': '%{cu}t', 'module': '%-m', 'level': '%l', 'pid': '%-P', 'tid': '%-T', 'oserror': '%-E', 'client': '%-a', 'msg': '%M'}' ApacheErrorLogFunctionPermission: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref ProcessApacheErrorLogFunction Action: lambda:InvokeFunction Principal: logs.amazonaws.com SourceArn: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:* SourceAccount: !Ref AWS::AccountId

このリソースは、CloudWatchLogsにLambda関数を呼び出すためのアクセス許可を付与します。

ApacheErrorLogSubscriptionFilter: Type: AWS::Logs::SubscriptionFilter DependsOn: ApacheErrorLogFunctionPermission Properties: LogGroupName: !Ref ApacheErrorLogGroup DestinationArn: !GetAtt ProcessApacheErrorLogFunction.Arn FilterPattern: '{$.msg != 'PHP Warning*' && $.msg != 'PHP Notice*'}'

最後に、Apacheエラーロググループのサブスクリプションフィルターを使用して、CloudWatchLogsをLambda関数にリンクします。 「PHPWarning」または「PHPNotice」で始まるメッセージを含むログがLambda関数の呼び出しをトリガーしないようにするフィルターパターンに注意してください。

最終的な考え、価格設定、および可用性

コストについて最後に一言:このソリューションは、ELKクラスターを運用するよりもはるかに安価です。 CloudWatchに保存されているログの価格はS3と同じレベルであり、Lambdaは無料枠の一部として月額100万回の通話を許可しています。これは、トラフィックが中程度から大量のWebサイト(CloudWatch Logsフィルターを使用している場合)にはおそらく十分です。特に、適切にコーディングし、エラーが多すぎない場合はそうです。

また、Lambda関数は最大1,000の同時呼び出しをサポートすることに注意してください。これを書いている時点では、これはAWSの厳しい制限であり、変更することはできません。ただし、上記の関数の呼び出しは約30〜40ミリ秒続くと予想できます。これは、かなり重いトラフィックを処理するのに十分な速度である必要があります。ワークロードが非常に激しく、この制限に達する場合は、Kinesisに基づくより複雑なソリューションが必要になる可能性があります。これについては、今後の記事で取り上げます。

基本を理解する

ELKスタックとは何ですか?

ELKはElasticsearch-Logstash-Kibanaの頭字語です。 Beats(ログとメトリックをLogstashに送信するツールのコレクション)やElastalert(Elasticsearch時系列データに基づいてアラートを生成する)など、追加のソフトウェアアイテムが必要になることがよくあります。

ELKスタックは無料ですか?

簡単な答えは:はい。 ELKスタックを構成するさまざまなソフトウェアアイテムにはさまざまなソフトウェアライセンスがありますが、通常はサポートなしで無料で使用できるライセンスがあります。ただし、ELKクラスターをセットアップして保守するのはあなた次第です。

ELKスタックはどのように機能しますか?

ELKスタックは高度に構成可能であるため、それを機能させる単一の方法はありません。たとえば、Apacheログエントリのパスは次のとおりです。Filebeatはエントリを読み取り、Logstashに送信して解析し、Elasticsearchに送信して保存してインデックスを作成します。その後、Kibanaはデータを取得して表示できます。

なぜより多くの起業家が新しい会社ではなくサーチファンドを作ることを選んでいるのですか?

財務プロセス

なぜより多くの起業家が新しい会社ではなくサーチファンドを作ることを選んでいるのですか?
インサイドセールスエグゼクティブ-東部地域

インサイドセールスエグゼクティブ-東部地域

その他

人気の投稿
AngularJSアプリでのFacebookログインとSatellizerの統合
AngularJSアプリでのFacebookログインとSatellizerの統合
Swiftプロパティのラッパーにアプローチする方法
Swiftプロパティのラッパーにアプローチする方法
ブロックチェーン、IoT、そして輸送の未来:モトロコインを理解する
ブロックチェーン、IoT、そして輸送の未来:モトロコインを理解する
F#チュートリアル:フルスタックF#アプリを構築する方法
F#チュートリアル:フルスタックF#アプリを構築する方法
WordPressのメンテナンスをスムーズにするための10のヒント
WordPressのメンテナンスをスムーズにするための10のヒント
 
デザインシステムとパターンを理解する
デザインシステムとパターンを理解する
SalesforceAppExchangeを使用したビジネスでの迅速な利益
SalesforceAppExchangeを使用したビジネスでの迅速な利益
より良いUXのためのUIスタイルガイドの作成
より良いUXのためのUIスタイルガイドの作成
動的アプリケーション向けの有望なRubyフレームワークであるVoltに会う
動的アプリケーション向けの有望なRubyフレームワークであるVoltに会う
Adobe CCがワイヤーフレームできることを誰が知っていましたか?
Adobe CCがワイヤーフレームできることを誰が知っていましたか?
人気の投稿
  • 中小企業の場合はscorpまたはccorp
  • node.jsは習得が難しい
  • さまざまな種類のLLC法人
  • s法人とc法人の違い
  • テンソルフローの使用方法
カテゴリー
プロセスとツール Kpiと分析 ライフスタイル バックエンド 技術 製品ライフサイクル 仕事の未来 その他 Webフロントエンド 設計プロセス

© 2021 | 全著作権所有

apeescape2.com