
圖7-1 elasticsearch
接下來筆者打算示範,如何使用TCP Log Plugin將Kong API Gateway 的Log都收攏起來。企業中通常會建置專屬的Log收攏平台,筆者在公司內是使用Splunk,而Open source project 則不得不提到Elasticsearch 這個資料庫。
筆者最早協助企業佈署Kong API Gateway的時候,其實是先接觸ELK(Elastic search + Logstash + Kibana)。那時候利用ELK將Log 收攏的時候,著實覺得十分有趣。後來公司因為政策原因,另行購買了Splunk供同仁紀錄與查錯使用,其實也非常好用。
不過這系列文準備要使用全部都是open source 的project來進行示範,因此今天就準備利用elasticsearch 與kibana,將Log收攏後進行查找。

圖 7-2 各節點架構
讀者可以先看一下圖7-2的架構圖,簡單說明如下:
首先先來關注到示範專案的檔案,ironman2025\case_ELK\docker-compose.yaml,有別於前一個範例,筆者節錄這次有新增的部分如下:
  elasticsearch:
    image: 'docker.elastic.co/elasticsearch/elasticsearch:9.0.3'
    container_name: elasticsearch
    restart: unless-stopped
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    volumes:
      - esdata:/usr/share/elasticsearch/data
    networks:
      - kong-net
  kibana:
    image: 'docker.elastic.co/kibana/kibana:9.0.3'
    container_name: kibana
    restart: unless-stopped
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch
    networks:
      - kong-net
上面的yaml可以看到,新增了elasticsearch以供存入Log,也能注意到port:9200,這個port可以提供tcp log的傳入,也能讓kibana連入使用。
接著,也可以注意到也新增了kibana,可以讓管理人員透過介面去查詢Log的狀態。
當確認elasticsearch 的位置後,接下來來設定kong.yml,請關注到示範專案下:ironman2025\case_ELK\1.Kong_declarative\declarative\kong.yml,同樣也擷取部分修改內容。
plugins:
- name: http-log
  config:
    http_endpoint: http://elasticsearch:9200/kong-logs/_doc
    method: POST
    content_type: application/json
這次筆者打算透過http log plugin 將log傳入elasticsearch,因此可以注意到上述的設定範例中,http_endpoint: http://elasticsearch:9200/kong-logs/_doc明確的將endpoint指向9200 port的位置。
另外值得一提的是,Kong log是以json的形式存在,不論是使用file log或是其他類型,因此同樣將content_type: application/json也清楚定義為json。
接下來關注到示範專案檔案:ironman2025\case_ELK\2.api_provider\case_withelk\Program.cs,筆者透過修改下面的程式碼,來將Log 透過Serilog套件,以http 的形式傳入elasticsearch。
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.File("logs/api-.log", rollingInterval: RollingInterval.Day)
    .WriteTo.Elasticsearch(new Serilog.Sinks.Elasticsearch.ElasticsearchSinkOptions(new Uri("http://elasticsearch:9200")) //寫入elastic endpoint
    {
        AutoRegisterTemplate = true,
        IndexFormat = "api-logs-{0:yyyy.MM.dd}"  //index在elasticsearch中的名稱
    })
    .CreateLogger();
由於dotnet 專案是自己撰寫的,因此需要自己進行docker build的動作,請到目錄ironman2025\case_ELK下,執行docker build 指令如下:
docker build -t withelk .\2.api_provider\case_withelk\

圖7-3 確認withelk image有被建立
現在一切就緒,請讀者到目錄ironman2025\case_ELK下,執行docker compose up -d,一切順利的話會看到圖7-4的畫面。

圖7-4 docker compose up 成功
接著,試試看打開瀏覽器,連線到 http://localhost:5601/,應該可以看到圖7-5的畫面,這時候已經確認,elasticsearch 與kibana已經就緒。

圖7-5 kibana
看起來環境都已經就緒,明天筆者就帶著讀者一起做實驗,並共同判讀Kibana中 Kong所傳入的Log。
明天見~