1.logStashとは
ELK(Elasticsearch+Logstash+Kibana)
Logstash とは正確には何ですか? 正式な説明
公式テキストの説明: Logstash は、複数のソースから同時にデータを取り込み、変換し、お気に入りの「リポジトリ」に送信できる、オープン ソースのサーバー側データ処理パイプラインです。
一般的な説明: Logstash は強力なデータ処理ツールであり、ログ処理によく使用されます。
Logstash には、これまでに 200 を超えるプラグインが用意されており、独自のプラグインを作成して提供できる柔軟性があります。コミュニティエコロジーも充実しており、安心してご利用いただけます。
2. logStash を使用する理由
通常、システムに障害が発生した場合、エンジニアは各サーバーにログインし、grep / sed / awk などの Linux スクリプト ツールを使用してログから障害の原因を特定する必要があります。ログ システムがない場合は、最初に要求を処理するサーバーを見つける必要があります。このサーバーに複数のインスタンスがデプロイされている場合は、各アプリケーション インスタンスのログ ディレクトリに移動して、ログ ファイルを見つける必要があります。各アプリケーション インスタンスは、ログのローリング ポリシー (たとえば、毎日ファイルを生成するなど)、ログの圧縮およびアーカイブ ポリシーなども設定します。
このような一連のプロセスの後、障害のトラブルシューティングと障害の原因の特定が間に合うまでに、多くのトラブルが発生しました。したがって、これらのログを一元管理し、一元検索機能を提供できれば、診断効率を向上させるだけでなく、システムの状況を包括的に把握し、イベント発生後の消防の受動性を回避することができます。
そのため、ELKの技術スタックを利用してログ集中管理機能を実現することができます。Elasticsearch にはデータ ストレージと分析機能しかなく、Kibana は視覚的な管理プラットフォームです。データの収集と照合の役割も欠落しており、これは Logstash が担当しています。
3. Logstashの動作原理
- 情報元
Logstash でサポートされているデータ ソースは多数あります。例えば、ログ機能は、ログ記録のあるログとログ配信機能のみがサポートされていますが、Spring Bootでは、ログ出力機能(データベースへの出力、ファイルへのデータ出力)をサポートするため、デフォルトでlogbackが推奨されています。
- Logstash パイプライン
全体が Logstash の機能です。
Logstash には、次の 3 つの非常に重要な機能が含まれています。
- 入力
入力ソースは通常、監視対象のホストとポートとして構成されます。DataSource は指定した IP とポートにログを出力し、Input ソースは監視後にデータ情報を収集できます。
- フィルター
フィルター機能は、収集した情報をフィルタリングする(追加処理)、この構成を省略することもできます(無処理)
- 出力
収集した情報の送信先。ELKテクノロジースタックでは、すべてElasticsearchに出力され、その後のデータ取得とデータ分析プロセスはElasticsearchに渡されます。
最終的な効果: 全体的な手順を経て、ログ情報の元の行を、Elasticsearch でストレージ用にサポートされているドキュメント (キーと値のペアの形式) の形式のデータに変換できます。
4.docker のインストール logStash
- logStash イメージをプルする
docker pull logstash:7.7.0
- コンテナを起動する
docker run -it -p 4560:4560 --name logstash -d logstash:7.7.0
- 設定を変更
コンテナに
docker exec -it ログスタッシュ /bin/bash
構成ファイルを変更する
vi /usr/share/logstash/config/logstash.yml
IPをelasticsearchアクセスアドレスIPに変更します
- 入力および出力構成の変更
コンテナーのコマンド ラインで入力を続ける
vi /usr/share/logstash/pipeline/logstash.conf
構成の説明:
input: 受信ログ入力設定
TCP: プロトコル
モード: logstash サービス
port: ポート、自分で指定します。デフォルト 4560
output: ログ処理出力
elasticsearch: 処理のために es に引き渡します
アクション: es の index コマンド。つまり、新しいコマンドです。
hosts: es のホスト
index: 保存されたログのインデックス。存在しない場合は、自動的に作成できます。デフォルトの型名は doc です
- コンテナを再起動します
コンテナー コマンド ラインを終了し、Linux ターミナルに入り、logstash コンテナーを再起動します。
docker restart ログスタッシュ
5. logback を使用して logStash にログを出力する
logStash 依存関係を追加
<!-- logstash依赖-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
logback.xml をインポートする
<?xml version="1.0" encoding="UTF-8"?>
<!--该日志将日志级别不同的log信息保存到不同的文件中 -->
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<springProperty scope="context" name="springAppName"
source="spring.application.name" />
<!-- 日志在工程中的输出位置 -->
<property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}" />
<!-- 控制台的日志输出样式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 日志输出编码 -->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- logstash远程日志配置-->
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.8.128:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="logstash" />
</root>
</configuration>
プロジェクト起動後、ログ情報がkibannaのelasticsearchに書き込まれているか確認
6. Kibanna でログ情報を表示する
すべてを表示するには、GET test_log/_search と入力します。
7. ログシステムを構築する
簡単な要件を考えると:
ログ システムを構築し、Elasticsearch でログ情報を照会するためのインターフェイスを提供します。(デフォルトでは 15 分以内のログ情報が照会されます)
7.1 pom.xml ファイルを変更する
<dependencies>
<!-- springDateElasticsearch依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- test依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- logstash依赖-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
7.2 application.yml 構成ファイルを変更する
spring:
elasticsearch:
rest:
uris: http://192.168.8.128:9200
7.3 エンティティの作成
Kibana で表示されるログ情報によると、message を除いて、いくつかの他の属性を含むクラス型であり、他の属性は単純な型の属性であることがわかります。
@version と @timestamp は、Spring データ Elasticsearch 3.x で @JsonProperty を使用して受信されることに注意してください。
@version と @timestamp は、Spring Data Elasticsearch 4.x の @Field の name 属性を使用して直接マッピングできます。
時間型は、format 属性を使用して変換する必要があります。カスタム メソッドは使用しないでください。
LogPojo エンティティ クラスの作成
@Data
@Document(indexName = "test_log")
public class LogPojo {
@Id
private String id;
@Field(type = FieldType.Keyword)
private String host;
@Field(type = FieldType.Long)
private Long port;
@Field(type = FieldType.Text)
private String message;
@Field(type = FieldType.Date,name = "@timestamp",format = DateFormat.date_time)
private Date timestamp;
@Field(type = FieldType.Text,name = "@version")
private String version;
// 不与ES中的属性对应。当自己业务中需要日志内容时
private MessagePojo messagePojo;
}
MessagePojoエンティティクラスを作成する(メッセージフィールドのログ情報を絞り込むため)
@Data
public class MessagePojo {
@JsonProperty("@timestamp")
private Date timestamp;
@JsonProperty("@version")
private String version;
private String message;
private String logger_name;
private String thread_name;
private String level;
private String level_value;
}
7.4 新しいサービスと実装クラス
public interface DemoService {
List<LogPojo> demo();
}
@Service
@Slf4j
public class DemoServiceImpl implements DemoService {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Override
public List<LogPojo> demo() {
// 获取当前时间
Calendar instance = Calendar.getInstance();
instance.add(Calendar.MINUTE,-15);
// 查询近15分钟的日志信息
Query query = new NativeSearchQuery(QueryBuilders.rangeQuery("@timestamp").gte(instance));
// 分页
query.setPageable(PageRequest.of(1,30));
SearchHits<LogPojo> search = elasticsearchRestTemplate.search(query, LogPojo.class);
log.error("查询结果总条数为: "+ search.getTotalHits());
List<SearchHit<LogPojo>> searchHits = search.getSearchHits();
List<LogPojo> list = new ArrayList<>();
searchHits.forEach(hits->{
LogPojo logPojo = hits.getContent();
String message = logPojo.getMessage();
ObjectMapper objectMapper = new ObjectMapper();
MessagePojo mp = null;
try {
mp = objectMapper.readValue(message, MessagePojo.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
logPojo.setMessagePojo(mp);
list.add(logPojo);
});
return list;
}
}
7.5 新しいコントローラーを作成する
@RestController
public class DemoController {
@Autowired
private DemoService demoService;
/**
* 获取es中最近15分钟的日志
* @return
*/
@RequestMapping("/")
public List<LogPojo> demo(){
return demoService.demo();
}
}
7.6 テスト結果
ブラウザに次のように入力します: http://127.0.0.1:8080/
以下に結果を示します。