FTP Log İzleme: Telegraf, InfluxDB ve Grafana ile Adım Adım Kurulum

YUNUS EMRE ATAY

ftp

FTP transfer loglarını (xferlog) izlemek için Telegraf, InfluxDB ve Grafana kullanmayı öğrenin. Bu rehber, adım adım kurulum, yapılandırma ve görselleştirme sürecini anlatmaktadır.


FTP sunucuları hâlâ birçok kurumda dosya aktarımı için yoğun şekilde kullanılıyor. Ancak bu transferlerin ne kadar sürdüğü, hangi IP adreslerinden geldiği, dosya boyutları ve başarısız aktarımlar gibi detayları izlemek çoğu zaman gözden kaçabiliyor.

Bu yazıda, Telegraf, InfluxDB ve Grafana üçlüsünü kullanarak FTP transfer loglarını (xferlog) nasıl toplayabileceğinizi, veritabanında saklayabileceğinizi ve Grafana ile görselleştirebileceğinizi adım adım anlatacağım.

Neden FTP Transferlerini İzlemelisiniz?

FTP loglarını izlemek sadece merak için değil, aynı zamanda sistem güvenliği ve performansı için kritik öneme sahiptir. İşte bazı nedenler:

  • Büyük dosya transferlerini takip etmek
  • Başarısız transferleri ve olağandışı aktiviteleri tespit etmek
  • Sunucu performansını izlemek ve iyileştirmek
  • Raporlama ve denetim ihtiyaçlarını karşılamak

1.) Giriş

Kuruluma başlamadan önce, firewall servisinin durdurulması ve SELinux’un devre dışı bırakılması önerilir.

Klasik bir FTP log kaydı örneği:

Mon Sep 15 15:40:20 2025 15 10.10.10.11 500 /tmp/test.kopya b _ i r ftpuser ftp 0 * c
  • Sat Sep 12 01:01:18 2025
    • Anlamı: İşlemin gerçekleştiği tarih ve saat.
    • Açıklama: Bu, transferin 15 Eylül 2025, saat 15:40:20’de (yerel saat) gerçekleştiğini gösterir.
  • 15
    • Anlamı: Transfer süresi (saniye cinsinden).
    • Açıklama: Dosya transferi 15 saniye sürmüş.
  • 10.10.10.11
    • Anlamı: İstemci IP adresi.
    • Açıklama: Transferi gerçekleştiren istemcinin IP adresi 10.10.10.11.
  • 500
    • Anlamı: Aktarılan dosya boyutu (bayt cinsinden).
    • Açıklama: Aktarılan dosya (test_hosts.txt) 500 bayt büyüklüğünde.
  • /tmp/test.kopya
    • Anlamı: Aktarılan dosyanın tam yolu.
    • Açıklama: Dosya, sunucuda /tmp/test.kopya dizininde bulunan test_hosts.txt adlı dosya.
  • b
    • Anlamı: Transfer türü.
    • Açıklama: b binary (ikili) transferi temsil eder. Diğer bir olasılık a (ASCII) olabilir. Bu durumda dosya binary modda aktarılmış.
  • _
    • Anlamı: Sıkıştırma yöntemi.
    • Açıklama: _ işareti, transfer sırasında sıkıştırma kullanılmadığını gösterir. Bazı FTP sunucuları sıkıştırma kullanabilir, bu durumda başka bir değer (örneğin, Z veya T) görünebilir.
  • i
    • Anlamı: Transfer yönü.
    • Açıklama: i incoming (gelen) transferi, yani dosyanın istemciden sunucuya yüklendiğini (upload) gösterir. o olsaydı, outgoing (giden), yani indirme (download) anlamına gelirdi.
  • r
    • Anlamı: Kullanıcı türü.
    • Açıklama: r remote (uzak) kullanıcıyı temsil eder. Bu, transferi yapan kullanıcının bir FTP istemcisi üzerinden bağlandığını gösterir. Yerel kullanıcılar için başka bir değer (örneğin, l) kullanılabilir.
  • ftpuser
    • Anlamı: Transferi gerçekleştiren kullanıcı adı.
    • Açıklama: FTP istemcisi, ftpuser adlı kullanıcı hesabıyla oturum açmış.
  • ftp
    • Anlamı: Servis adı.
    • Açıklama: Transferin FTP protokolü üzerinden gerçekleştiğini belirtir. Başka protokoller (örneğin, SFTP) farklı bir değer alabilir.
  • 0
    • Anlamı: Kimlik doğrulama yöntemi.
    • Açıklama: 0, anonim oturum olmadığını ve gerçek bir kullanıcı hesabıyla oturum açıldığını gösterir. Anonim FTP için 1 kullanılır.
  • *
    • Anlamı: Kimlik doğrulama için ek bilgi.
    • Açıklama: * genellikle ek bilgi olmadığını veya parola gibi hassas bilgilerin gizlendiğini gösterir.
  • c
    • Anlamı: Transferin tamamlanma durumu.
    • Açıklama: c complete (tamamlandı) anlamına gelir, yani dosya transferi başarıyla tamamlanmış. Eğer i olsaydı, incomplete (tamamlanmadı) anlamına gelirdi.

2.) Gerekli Dosyaların Indirilmesi ve Kurulması

Linux tabanlı sunucunuza Telegraf, Influxdb ve Grafana kurulumu için gerekli dosyalar:

wget https://repos.influxdata.com/rhel/7/x86_64/stable/influxdb2-2.7.12-1.x86_64.rpm

wget https://repos.influxdata.com/rhel/7/x86_64/stable/telegraf-1.36.1-1.x86_64.rpm

wget https://dl.grafana.com/grafana-enterprise/release/12.1.1/grafana-enterprise_12.1.1_16903967602_linux_amd64.rpm

wget https://dl.influxdata.com/influxdb/releases/influxdb2-client-2.7.5-linux-amd64.tar.gz

Gerekli rpm dosyalarının kurulması ve servislerinin başlatılması:

rpm -ivh influxdb2-2.7.12-1.x86_64.rpm
rpm -ivh telegraf-1.36.1-1.x86_64.rpm
rpm -ivh grafana-enterprise_12.1.1_16903967602_linux_amd64.rpm
systemctl start grafana-server.service
systemctl start influxdb.service
systemctl start telegraf.service
systemctl enable grafana-server.service
systemctl enable influxdb.service
systemctl enable telegraf.service

Influx CLI Kurulumu:

tar -xzvf influxdb2-client-2.7.5-linux-amd64.tar.gz
mv influx /usr/bin/influx
chmod +x /usr/bin/influx
influx version
Influx CLI dev (git: a79a2a1b825867421d320428538f76a4c90aa34c) build_date: 2024-04-16T14:34:32Z

3.) InfluxDB Setup

InfluxDB servisi default olarak localhost:8086 host ve port bilgisi ile çalışmaktadır.

localhost:8086 veya <host_ip>:8086 adresine tarayıcıdan girelim ve gerekli ayarlamaları yapalım:

Username 			=> admin
Password			=> 12345678
Initial Organization Name 	=> oraclius.org
Initial Bucket Name		=> oraclius.bucket

admin's Token
KvMrs65Iaqy7XON6Fzi2_e87A34B2GpZZjHeBHW8SO_C0bdGeQ4EmnrB851FzKOCLqpAYNgNEgUXU7BzATx3UQ==

All Access API Token
2CGYUEiOrBowrsCR4uYTbUPaSHApRbyt6YyDuxHxj2K7rgTISo1KdVryGtyXm51HLofWjHAETr9erEpWlrFk6A==

4.) Telegrac Conf Dosyasının Düzenlenmesi

InfluxDB Setup adımında elde ettiğimiz bazı bilgiler ile Telegraf ile topladığımız metrikleri InfluxDB’ye aktarılmasını sağlayacağız:

vi /etc/telegraf/telegraf.conf

[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = "0s"

[[outputs.influxdb_v2]]
  urls = ["http://10.10.10.11:8086"]
  token = "2CGYUEiOrBowrsCR4uYTbUPaSHApRbyt6YyDuxHxj2K7rgTISo1KdVryGtyXm51HLofWjHAETr9erEpWlrFk6A=="
  organization = "oraclius.org"
  bucket = "oraclius.bucket"

[[inputs.tail]]
  files = ["/var/log/xferlog"]
  from_beginning = false
  name_override = "ftp_transfers"
  data_format = "grok"
  grok_patterns = [
  '%{DAY:day} %{MONTH:month} %{MONTHDAY:daynum} %{TIME:log_time} %{YEAR:year} %{NUMBER:transfer_number:int} %{IP:client_ip} %{NUMBER:bytes:int} %{DATA:file_path} %{WORD:transfer_type} %{WORD:compression_method} %{WORD:transfer_direction} %{WORD:user_type} %{WORD:ftp_user} %{WORD:service_name} %{NUMBER:auth_method:int} %{DATA:auth_method_extra} %{WORD:status}'
]
  initial_read_offset = "end"

[[processors.starlark]]
  namepass = ["ftp_transfers"]
  source = '''
def apply(metric):
    months = {
        "Jan":"01","Feb":"02","Mar":"03","Apr":"04","May":"05","Jun":"06",
        "Jul":"07","Aug":"08","Sep":"09","Oct":"10","Nov":"11","Dec":"12"
    }

    month = metric.fields.get("month")
    daynum = str(metric.fields.get("daynum"))
    year = str(metric.fields.get("year"))
    log_time = metric.fields.get("log_time")

    if month != None and daynum != None and year != None and log_time != None:
        mon = months.get(month, "01")
        if len(daynum) == 1:
            daynum = "0" + daynum
        formatted = daynum + "/" + mon + "/" + year + " " + log_time
        metric.fields["ftp_date"] = formatted

    return metric
'''

Telegraf conf dosyasını değiştirdiğimiz için Telegraf servisini restart etmemiz gerekiyor.

systemctl restart telegraf.service

5.) Test Amaçlı Ftp Log Üretme

Telegraf’ın FTP log dosyasını (xferlog) doğru şekilde okuyup okumadığını test edelim:

touch /tmp/ftp.file

[root@ftp log]# touch /tmp/ftp.file
[root@ftp log]# ftp 10.10.10.11
Connected to 10.10.10.11 (10.10.10.11).
220 (vsFTPd 3.0.2)
Name (10.10.10.11:root): test
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put /tmp/ftp.file /tmp/send.file
local: /tmp/ftp.file remote: /tmp/send.file
227 Entering Passive Mode (10,10,10,11,69,196).
150 Ok to send data.
226 Transfer complete.
ftp> bye
221 Goodbye.
[root@ftp log]# cat xferlog 
Tue Sep 16 17:56:36 2025 1 10.10.10.11 0 /tmp/send.file b _ i r test ftp 0 * c

Telegraf’ı debug modunda çalıştırıp hataları görebiliriz:

[root@ftp Downloads]# telegraf --config /etc/telegraf/telegraf.conf --debug

# telegraf --config /etc/telegraf/telegraf.conf --debug
2025-09-16T14:58:43Z I! Loading config: /etc/telegraf/telegraf.conf
2025-09-16T14:58:43Z I! Starting Telegraf 1.36.1 brought to you by InfluxData the makers of InfluxDB
2025-09-16T14:58:43Z I! Available plugins: 239 inputs, 9 aggregators, 35 processors, 26 parsers, 65 outputs, 6 secret-stores
2025-09-16T14:58:43Z I! Loaded inputs: tail
2025-09-16T14:58:43Z I! Loaded aggregators:
2025-09-16T14:58:43Z I! Loaded processors: starlark
2025-09-16T14:58:43Z I! Loaded secretstores:
2025-09-16T14:58:43Z I! Loaded outputs: influxdb_v2
2025-09-16T14:58:43Z I! Tags enabled: host=ftp.host
2025-09-16T14:58:43Z I! [agent] Config: Interval:10s, Quiet:false, Hostname:"ftp.host", Flush Interval:10s
2025-09-16T14:58:43Z W! [agent] The default value of 'skip_processors_after_aggregators' will change to 'true' with Telegraf v1.40.0! If you need the current default behavior, please explicitly set the option to 'false'!
2025-09-16T14:58:43Z D! [agent] Initializing plugins
2025-09-16T14:58:43Z D! [agent] Connecting outputs
2025-09-16T14:58:43Z D! [agent] Attempting connection to [outputs.influxdb_v2]
2025-09-16T14:58:43Z D! [agent] Successfully connected to outputs.influxdb_v2
2025-09-16T14:58:43Z D! [agent] Starting service inputs
2025-09-16T14:58:43Z D! [inputs.tail] Tail added for "/var/log/xferlog"
2025-09-16T14:58:53Z D! [outputs.influxdb_v2] Wrote batch of 1 metrics in 5.647823ms
2025-09-16T14:58:53Z D! [outputs.influxdb_v2] Buffer fullness: 0 / 10000 metrics

Debug mode’da xferlog’a yazılan satırı buldu ve işlemeyi başardı.


6.) Grafana Dashboard Oluşturma

Grafana Default olarak 3000 port’unda çalışmaktadır.
localhost:300 veya <ip>:3000 adresine tarayıcıdan girelim ve gerekli ayarlamaları yapalım:

İlk girişde sorduğu Username ve Password default olarak admin/admin olarak gelmektedir.

Sağ menüden InfluxDB bağlantısı için yeni bir Data Connection oluşturalım:

Connections => Add new connection => InfluxDB => Add new data source

InfluxDB Bağlantı Ayarları:

  • Query Language => Flux
  • HTTP URL => http://10.10.10.11:8086
  • Organization => oraclius.org
  • Token => 2CGYUEiOrBowrsCR4uYTbUPaSHApRbyt6YyDuxHxj2K7rgTISo1KdVryGtyXm51HLofWjHAETr9erEpWlrFk6A==
  • Default Bucket => oraclius.bucket

Grafana ile InfluxDB’ye başarılı bir bağlantı yapıldı şimdi hazır bir Dashboard import edip ftp loglarını analiz edelim:

Grafan => Dashboard => New => Import Dashboard

{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": {
          "type": "grafana",
          "uid": "-- Grafana --"
        },
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "description": "YEATAY\nhttps://oraclius.com.tr/",
  "editable": true,
  "fiscalYearStartMonth": 0,
  "graphTooltip": 0,
  "id": 2,
  "links": [],
  "panels": [
    {
      "datasource": {
        "type": "influxdb",
        "uid": "eey9efurcmvb4c"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisBorderShow": false,
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "barWidthFactor": 0.6,
            "drawStyle": "line",
            "fillOpacity": 0,
            "gradientMode": "none",
            "hideFrom": {
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "insertNulls": false,
            "lineInterpolation": "smooth",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": 0
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "overrides": [
          {
            "matcher": {
              "id": "byName",
              "options": "bytes {host=\"ftp.host\", path=\"/var/log/xferlog\"}"
            },
            "properties": [
              {
                "id": "unit",
                "value": "bytes"
              }
            ]
          }
        ]
      },
      "gridPos": {
        "h": 11,
        "w": 12,
        "x": 0,
        "y": 0
      },
      "id": 5,
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": false
        },
        "tooltip": {
          "hideZeros": false,
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "12.1.1",
      "targets": [
        {
          "query": "from(bucket: \"oraclius.bucket\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"ftp_transfers\")\n  |> filter(fn: (r) => r[\"_field\"] == \"bytes\")\n  |> aggregateWindow(every: 5m, fn: sum, createEmpty: false)\n  |> yield(name: \"total_bytes_5m\")\n",
          "refId": "A"
        }
      ],
      "title": "AVERAGE FILE SIZE",
      "transformations": [
        {
          "id": "organize",
          "options": {
            "excludeByName": {
              "Time": false,
              "bytes {host=\"grafana.ftp\", path=\"/var/log/xferlog\"}": false
            },
            "includeByName": {},
            "indexByName": {},
            "renameByName": {}
          }
        }
      ],
      "type": "timeseries"
    },
    {
      "datasource": {
        "type": "influxdb",
        "uid": "eey9efurcmvb4c"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisBorderShow": false,
            "axisCenteredZero": false,
            "axisColorMode": "series",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "barWidthFactor": 0.6,
            "drawStyle": "line",
            "fillOpacity": 0,
            "gradientMode": "none",
            "hideFrom": {
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "insertNulls": false,
            "lineInterpolation": "smooth",
            "lineStyle": {
              "fill": "solid"
            },
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": 0
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 11,
        "w": 12,
        "x": 12,
        "y": 0
      },
      "id": 3,
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": false
        },
        "tooltip": {
          "hideZeros": false,
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "12.1.1",
      "targets": [
        {
          "query": "from(bucket: \"oraclius.bucket\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r._measurement == \"ftp_transfers\")\n  |> aggregateWindow(every: 5m, fn: count, createEmpty: false)\n  |> yield(name: \"file_count\")\n",
          "refId": "A"
        }
      ],
      "title": "AVERAGE FILE COUNT",
      "type": "timeseries"
    },
    {
      "datasource": {
        "type": "influxdb",
        "uid": "eey9efurcmvb4c"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "custom": {
            "align": "center",
            "cellOptions": {
              "type": "color-text",
              "wrapText": true
            },
            "filterable": true,
            "inspect": true
          },
          "fieldMinMax": false,
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": 0
              }
            ]
          }
        },
        "overrides": [
          {
            "matcher": {
              "id": "byName",
              "options": "FTP DATE"
            },
            "properties": [
              {
                "id": "custom.width",
                "value": 175
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "FTP TIME"
            },
            "properties": [
              {
                "id": "custom.width",
                "value": 111
              },
              {
                "id": "unit",
                "value": "s"
              },
              {
                "id": "thresholds",
                "value": {
                  "mode": "absolute",
                  "steps": [
                    {
                      "color": "green",
                      "value": 0
                    },
                    {
                      "color": "orange",
                      "value": 100
                    },
                    {
                      "color": "red",
                      "value": 180
                    }
                  ]
                }
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "CLIENT IP"
            },
            "properties": [
              {
                "id": "custom.width",
                "value": 140
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "FILE SIZE"
            },
            "properties": [
              {
                "id": "unit",
                "value": "bytes"
              },
              {
                "id": "custom.width",
                "value": 119
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "FTP PATH"
            },
            "properties": [
              {
                "id": "custom.width"
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "TRANSFER TYPE"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "a": {
                        "index": 1,
                        "text": "a → ASCII"
                      },
                      "b": {
                        "index": 0,
                        "text": "b → binary"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 150
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "COMPRESSION METHOD"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "T": {
                        "index": 2,
                        "text": "tar/stream"
                      },
                      "Z": {
                        "index": 1,
                        "text": "Zmodem"
                      },
                      "_": {
                        "index": 0,
                        "text": "no compress"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 207
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "TRANSFER DIRECTORY"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "i": {
                        "color": "green",
                        "index": 0,
                        "text": "incoming"
                      },
                      "o": {
                        "color": "blue",
                        "index": 1,
                        "text": "outgoing"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 200
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "USER TYPE"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "l": {
                        "color": "blue",
                        "index": 1,
                        "text": "local"
                      },
                      "r": {
                        "color": "green",
                        "index": 0,
                        "text": "remote"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 118
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "FTP USER"
            },
            "properties": [
              {
                "id": "custom.width",
                "value": 112
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "SERVICE NAME"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "ftp": {
                        "index": 0,
                        "text": "FTP"
                      },
                      "ftps": {
                        "index": 2,
                        "text": "FTPS"
                      },
                      "scp": {
                        "index": 3,
                        "text": "SCP"
                      },
                      "sftp": {
                        "index": 1,
                        "text": "SFTP"
                      },
                      "tftp": {
                        "index": 4,
                        "text": "TFTP"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 140
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "AUTH METHOD"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "0": {
                        "color": "green",
                        "index": 0,
                        "text": "normal"
                      },
                      "1": {
                        "color": "blue",
                        "index": 1,
                        "text": "anonymous"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 143
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "AUTH METHOD EXTRA"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "*": {
                        "index": 0,
                        "text": "NO EXTRA"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 196
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "STATUS"
            },
            "properties": [
              {
                "id": "mappings",
                "value": [
                  {
                    "options": {
                      "c": {
                        "color": "green",
                        "index": 0,
                        "text": "COMPLETE"
                      },
                      "i": {
                        "color": "red",
                        "index": 1,
                        "text": "INCOMPLETE"
                      }
                    },
                    "type": "value"
                  }
                ]
              },
              {
                "id": "custom.width",
                "value": 139
              }
            ]
          }
        ]
      },
      "gridPos": {
        "h": 15,
        "w": 24,
        "x": 0,
        "y": 11
      },
      "id": 1,
      "options": {
        "cellHeight": "md",
        "footer": {
          "countRows": false,
          "enablePagination": false,
          "fields": [
            "transfer_number",
            "bytes"
          ],
          "reducer": [
            "sum"
          ],
          "show": true
        },
        "showHeader": true,
        "sortBy": [
          {
            "desc": true,
            "displayName": "FTP DATE"
          }
        ]
      },
      "pluginVersion": "12.1.1",
      "targets": [
        {
          "datasource": {
            "type": "influxdb",
            "uid": "cexyp8mcclpfkd"
          },
          "query": "from(bucket: \"oraclius.bucket\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r._measurement == \"ftp_transfers\")",
          "refId": "A"
        }
      ],
      "title": "FTP TRANSFER",
      "transformations": [
        {
          "id": "merge",
          "options": {}
        },
        {
          "id": "organize",
          "options": {
            "excludeByName": {
              "Time": true,
              "day": true,
              "daynum": true,
              "log_time": true,
              "month": true,
              "year": true
            },
            "includeByName": {},
            "indexByName": {
              "Time": 0,
              "auth_method": 12,
              "auth_method_extra": 13,
              "bytes": 4,
              "client_ip": 3,
              "compression_method": 7,
              "day": 15,
              "daynum": 17,
              "file_path": 5,
              "ftp_date": 1,
              "ftp_user": 10,
              "log_time": 18,
              "month": 16,
              "service_name": 11,
              "status": 14,
              "transfer_direction": 8,
              "transfer_number": 2,
              "transfer_type": 6,
              "user_type": 9,
              "year": 19
            },
            "orderByMode": "manual",
            "renameByName": {
              "Time": "",
              "auth_method": "AUTH METHOD",
              "auth_method_extra": "AUTH METHOD EXTRA",
              "bytes": "FILE SIZE",
              "client_ip": "CLIENT IP",
              "compression_method": "COMPRESSION METHOD",
              "daynum": "",
              "file_path": "FTP PATH",
              "ftp_date": "FTP DATE",
              "ftp_user": "FTP USER",
              "service_name": "SERVICE NAME",
              "status": "STATUS",
              "transfer_direction": "TRANSFER DIRECTORY",
              "transfer_number": "FTP TIME",
              "transfer_type": "TRANSFER TYPE",
              "user_type": "USER TYPE"
            }
          }
        },
        {
          "id": "convertFieldType",
          "options": {
            "conversions": [
              {
                "destinationType": "number",
                "targetField": "FTP TIME"
              },
              {
                "destinationType": "number",
                "targetField": "FILE SIZE"
              },
              {
                "dateFormat": "DD/MM/YYYY HH:mm:ss",
                "destinationType": "time",
                "targetField": "FTP DATE"
              }
            ],
            "fields": {}
          }
        },
        {
          "id": "sortBy",
          "options": {
            "fields": {},
            "sort": [
              {
                "desc": true,
                "field": "FTP DATE"
              }
            ]
          }
        }
      ],
      "type": "table"
    }
  ],
  "preload": false,
  "schemaVersion": 41,
  "tags": [],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-30m",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "",
  "title": "FTP Transfers Dashboard",
  "uid": "1",
  "version": 4
}

7.) Test Verisi Ile Sıstemi Test Etme

Bu adımda bir bash script ile gerçek dışı ftp kayıtları oluşturup xferlog dosyasında kayır oluşturarak sistemimizi kontrol edeceğiz:

#!/usr/bin/env bash
# fake_xferlog_generator.sh
# Kullanım örneği:
#   ./fake_xferlog_generator.sh               # varsayılan: rate=100/min, output=/var/log/xferlog, sonsuz
#   ./fake_xferlog_generator.sh 200 /tmp/xferlog 600 0.9  # 200/min, /tmp/xferlog, 600 kayıt sonra dur, başarı oranı 90%

RATE_PER_MIN=${1:-100}           # kayıt/dakika
OUTFILE=${2:-/var/log/xferlog}   # hedef dosya (yazma izinlerini kontrol et)
MAX_COUNT=${3:-0}                # 0 => sonsuz, >0 => o kadar kayıt sonra çık
SUCCESS_RATIO=${4:-0.85}         # başarı yüzdesi (0..1)
MAX_BYTES=${5:-10485760}         # maksimum byte (default 10 MiB)

INTERVAL=$(awk -v r="$RATE_PER_MIN" 'BEGIN{printf "%.6f", 60.0/r}')
echo "RATE_PER_MIN=$RATE_PER_MIN, INTERVAL=$INTERVAL s, OUTFILE=$OUTFILE, MAX_COUNT=$MAX_COUNT, SUCCESS_RATIO=$SUCCESS_RATIO, MAX_BYTES=$MAX_BYTES"

# Örnek havuzlar — istersen burayı genişlet/ değiştir
USERS=(alice bob carol dave ftpuser_1 ftpuser_2 serviceacct)
FILES=("/home/ftpuser_1/readme.txt" "/home/ftpuser_2/upload.bin" "/srv/files/image.iso" "/data/backups/db.tar.gz" "/home/ftpuser_3/test_hosts_1.txt" "/tmp/testfile.dat")
CLIENT_NETS=("10.10.10." "10.0.0." "192.168.1." "172.16.0.")
SERVICES=(ftp sftp ftps scp tftp)
TRANSFER_TYPES=(b a)             # binary / ascii
COMPRESSION_METHODS=(_ Z T)      # '_' = none, Z,T = some servers
TRANSFER_DIR=(i o)               # incoming (upload) / outgoing (download)
USER_TYPES=(r l)                 # remote / local
AUTH_METHODS=(0 1)               # 0=real user, 1=anonymous
STATUS=(c i)                     # complete / incomplete

# ensure outfile exists and is writable (try to create)
touch "$OUTFILE" 2>/dev/null || { echo "Hata: $OUTFILE dosyasına yazamıyorum. İzinleri kontrol et veya başka bir yol ver."; exit 1; }

# helper: random int [0,n-1]
rand() { echo $((RANDOM % $1)); }

# helper: random ip from prefix
rand_ip() {
  prefix=${CLIENT_NETS[$((RANDOM % ${#CLIENT_NETS[@]}))]}
  echo "${prefix}$((RANDOM % 254 + 1))"
}

# helper: random element
pick() { arr=("$@"); echo "${arr[$((RANDOM % ${#arr[@]}))]}"; }

# generate random timestamp within last N seconds (default 48h)
RANGE_SEC=$((48*3600))
rand_timestamp() {
  now=$(date +%s)
  offset=$((RANDOM % RANGE_SEC))
  t=$((now - offset))
  date -u -d "@$t" '+%a %b %d %T %Y' 2>/dev/null || date -d "@$t" '+%a %b %d %T %Y'
}

count=0
transfer_number=1

while true; do
  # stop condition
  if [ "$MAX_COUNT" -ne 0 ] && [ "$count" -ge "$MAX_COUNT" ]; then
    echo "Üretim tamamlandı: $count kayıt üretildi."
    exit 0
  fi

  # build random record
  ts=$(rand_timestamp)                    # "Sat Sep 13 06:31:18 2025"
  tn=$transfer_number
  cip=$(rand_ip)
  bytes=$(( (RANDOM * RANDOM) % (MAX_BYTES+1) )) # biraz dağılım için çarpılıyor
  file=$(printf "%s" "${FILES[$((RANDOM % ${#FILES[@]}))]}")
  ttype=${TRANSFER_TYPES[$((RANDOM % ${#TRANSFER_TYPES[@]}))]}
  comp=${COMPRESSION_METHODS[$((RANDOM % ${#COMPRESSION_METHODS[@]}))]}
  dir=${TRANSFER_DIR[$((RANDOM % ${#TRANSFER_DIR[@]}))]}
  utype=${USER_TYPES[$((RANDOM % ${#USER_TYPES[@]}))]}
  user=${USERS[$((RANDOM % ${#USERS[@]}))]}
  svc=${SERVICES[$((RANDOM % ${#SERVICES[@]}))]}
  auth=${AUTH_METHODS[$((RANDOM % ${#AUTH_METHODS[@]}))]}
  # auth_method_extra: ya '*' ya kısa token
  if (( RANDOM % 10 == 0 )); then
    am_extra="tok$(printf '%04d' $((RANDOM % 10000)))"
  else
    am_extra="*"
  fi
  # success or fail by ratio
  rprob=$(awk -v r="$RANDOM" 'BEGIN{printf "%.6f", r/32767}')
  if (( $(awk -v p="$rprob" -v s="$SUCCESS_RATIO" 'BEGIN{print (p < s)}') )); then
    stat="c"
  else
    stat="i"
  fi

  # Compose xferlog line (matches örnek format)
  # Format: "Sat Sep 13 06:31:18 2025 100 10.10.10.11 10 /path/to/file b _ i r ftpuser ftp 0 * c"
  line="$ts $tn $cip $bytes $file $ttype $comp $dir $utype $user $svc $auth $am_extra $stat"

  # Append to file (atomic append)
  printf "%s\n" "$line" >> "$OUTFILE"

  # increment counters
  transfer_number=$((transfer_number + 1))
  count=$((count + 1))

  # sleep interval
  sleep "$INTERVAL"
done

Telegraf logunu kontrol edelim olası hatalar için:

# telegraf --config /etc/telegraf/telegraf.conf --debug
...
2025-09-16T15:24:06Z D! [outputs.influxdb_v2] Wrote batch of 16 metrics in 2.644223ms
2025-09-16T15:24:06Z D! [outputs.influxdb_v2] Buffer fullness: 0 / 10000 metrics
2025-09-16T15:24:16Z D! [outputs.influxdb_v2] Wrote batch of 16 metrics in 2.692254ms
2025-09-16T15:24:16Z D! [outputs.influxdb_v2] Buffer fullness: 0 / 10000 metrics
2025-09-16T15:24:26Z D! [outputs.influxdb_v2] Wrote batch of 16 metrics in 3.535188ms
2025-09-16T15:24:26Z D! [outputs.influxdb_v2] Buffer fullness: 0 / 10000 metrics
2025-09-16T15:24:36Z D! [outputs.influxdb_v2] Wrote batch of 17 metrics in 3.50399ms
2025-09-16T15:24:36Z D! [outputs.influxdb_v2] Buffer fullness: 0 / 10000 metrics
...

Belirli aralıkta gelen ftp transferlerini güzel bir şekilde yakalıyor.

%s için bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Hey!

Merhaba! Ben EMRE, teknoloji, yazılım veri tabanı ve veri analitiği alanlarına tutkuluyum. Bu blogda, öğrendiklerimi ve tecrübelerimi paylaşarak faydalı içerikler sunmayı hedefliyorum. Boş zamanlarımda yeni teknolojiler keşfetmeyi, yazmayı ve kendimi geliştirmeyi seviyorum.

ıletısım adreslerım