[RAILS] Créer un serveur fluentd pour les tests

Dans le processus de création d'un système qui utilise fluentd, je me demandais comment tester que les données avaient été envoyées à fluentd en premier lieu, j'ai donc étudié diverses choses.

Chose que tu veux faire

Dans le processus de création d'un système qui utilise fluentd, je souhaite écrire un test rapide pour confirmer que les données sont envoyées à fluentd.

politique

Je veux raccourcir le temps de test autant que possible lors de l'exécution de CI, donc je veux lier les données générées par FluentLogger pour les sortir en temps réel autant que possible.

J'avais l'habitude d'écrire le code pour ouvrir la socket et attendre par moi-même, mais depuis que la version a augmenté et que SSL est devenu impliqué, cela est devenu gênant, alors j'aimerais faire quelque chose avec le plugin autant que possible.

Comme j'utilise souvent docker pour configurer le middleware environnant lors de la conversion de CI, j'ai essayé de mettre Elasticsearch dans le kit de middleware une fois auparavant, mais j'ai volontairement construit Elasticsearch que je n'ai pas appelé directement et elasticsearch-ruby pour le test C'est aussi paresseux de le mettre et de le connecter. .. .. Surtout avec l'image officielle, cela ne se produit pas avec un seul nœud, et il est difficile de suivre et de mettre à jour avec tous les micro-services lorsque la version change, donc je voudrais tester sans middleware supplémentaire autant que possible.

Etude de méthode

Temps réel

La mise en mémoire tampon fluentd est toujours effectuée en ajustant la valeur de flush_interval, mais s'il s'agit d'un test, il semble que vous puissiez utiliser flush_mode = immédiat

Convivialité en CI

Cette fois, quand j'ai réfléchi à la façon de faire bon usage de Redis, qui est également utilisé dans ActiveJob etc., il y avait un bon plug-in dans la Official plug-in list, alors je l'ai essayé. Essayer.

Il y avait aussi MySQL, mais la structure des données envoyées depuis FluentLogger est assez différente, donc le plug-in redis qui le met en place était plus approprié.

Je l'ai essayé

Nous procéderons à l'installation Gem et aux réglages fluides nécessaires en fonction de l'étude de la méthode.

0. Préparation

Quant à gem, il suffit qu'il y ait un plug fluent-plugin-redis-store en plus du corps principal, donc je vais tout mettre ensemble

command


gem install fluentd fluent-plugin-redis-store --no-document

J'omettrai l'installation de Redis, mais construirai redis en utilisant brew ou docker.

Puisque fluentd est reçu de forward et envoyé à redis_store, fluent.conf ressemble à ceci.

fluent.conf


<source>
  @type forward
  @id input1
  @label @mainstream
  port 24224
</source>

<label @mainstream>
  <filter **>
    @type record_transformer
    <record>
      tag ${tag}
    </record>
  </filter>
  <match **>
    @type copy
    <store>
      @type stdout
    </store>
    <store>
      @type redis_store
      key_path tag
      <buffer>
        flush_mode immediate
      </buffer>
    </store>
  </match>
</label>

Ce que je fais est comme ça.

C'est un bonus de le mettre sur stdout, mais si vous le sortez, il est facile de le débuck plus tard.

Écrivez ceci dans . / Fluent.conf et lancez fluentd

fluentd -c fluent.conf

Maintenant que je suis prêt, j'aimerais ajouter les données, mais il est plus facile de comprendre le mouvement si vous surveillez Redis, alors ouvrez une autre fenêtre et surveillez-la.

redis-cli monitor

1. Jetez des données à fluentd

Où envoyer des données à fluentd, l'application actuelle utilise fluent-logger-ruby pour envoyer des données, mais cette fois `fluent-cat Essayez d'utiliser ʻ comme substitut

echo '{ "key" : "sample" }' | bundle exe fluent-cat debug.test

Il s'agit d'une commande qui envoie les données avec la balise debug.test et l'horodatage de l'heure actuelle aux données {" key ":" sample "}. S'il n'est pas défini, il sera adressé à localhost, de sorte que les données seront envoyées au serveur fluentd construit ci-dessus.

Ensuite, la sortie suivante sera sortie vers la sortie standard du côté fluent.

fenêtre d'exécution fluide


2020-11-03 09:37:28.016591000 +0900 debug.test: {"key":"sample","tag":"debug.test"}

Ceci est généré par @type stdout défini dans fluent.conf, et il peut être confirmé que le filtre a une balise ajoutée après avoir effectivement reçu les données.

De plus, en regardant la fenêtre de surveillance Redis, elle s'affiche comme suit.

redis-fenêtre d'exécution cli


1604363848.025602 [0 172.28.0.1:40998] "zadd" "debug.test" "1604363848.016591" "{\"key\":\"sample\",\"tag\":\"debug.test\"}"

Il est ajouté comme décrit dans le readme du plugin. Le paramétrage de «key_path tag» est effectif pour key, et «debug.test», qui est la valeur du tag inclus dans les données, est défini.

2. Confirmation des données lancées

Essayez d'obtenir les données de Redis.

redis-cli zrange debug.test 0 -1 withscores
1) "{\"key\":\"sample\",\"tag\":\"debug.test\"}"
2) "1604363848.016591"

Étant donné que l'horodatage est un score, il est trié pour que vous puissiez en mettre beaucoup.

Au fait, le rubis est comme ça.

require 'redis'

Redis.new.zrange 'debug.test', 0, -1, withscores: true

output


 => [["{\"key\":\"sample\",\"tag\":\"debug.test\"}", 1604363848.016591]]

Pour le moment, la valeur peut être prise simplement, il semble donc relativement facile à utiliser.

prime

Tenez compte de la convivialité dans les tests parallèles

Lors de l'exécution de tests en parallèle à l'aide de «parallel_tests» ou de «test-queue», il devient nécessaire de déterminer quel processus de test est entré dans le journal. À ce moment-là, vous pouvez inclure l'ID de processus dans les données à envoyer et l'utiliser pour définir la clé.

Je veux mettre l'ID de processus, l'heure et l'ID de demande dans le fichier journal Rails, donc je ne pense pas que cela causera un dommage.

Dans ce cas, les données à envoyer seront les suivantes

{ "key" : "sample", "pid" : 123 }

Parallèlement à cela, changez fluent.conf comme suit.

  <label @mainstream>
    <filter **>
      @type record_transformer
      <record>
        tag ${tag}
+       tag_with_pid '${tag}.${record["pid"]}'
      </record>
    </filter>
    <match **>
      @type copy
      <store>
        @type stdout
      </store>
      <store>
        @type redis_store
-       key_path tag
+       key_path tag_with_pid
        <buffer>
          flush_mode immediate
        </buffer>
      </store>
    </match>
  </label>

Maintenant que l'ID de processus est entré dans la clé lors de son enregistrement dans Redis, utilisez cet ID de processus pour identifier le journal de votre propre processus et évaluez-le pour déterminer si les données ont été réellement envoyées. Vous pourrez.

Changer la destination de Redis

Il semble que vous puissiez modifier le paramètre sous la forme suivante comme décrit dans README

  <label @mainstream>
    <filter **>
      @type record_transformer
      <record>
        tag ${tag}
      </record>
    </filter>
    <match **>
      @type copy
      <store>
        @type stdout
      </store>
      <store>
        @type redis_store
        key_path tag
+       host 10.0.0.1
+       db   11
        <buffer>
          flush_mode immediate
        </buffer>
      </store>
    </match>
  </label>

Aide lors de l'utilisation avec RSpec et Cucumber

Lorsque vous l'utilisez dans un test, si vous créez un assistant comme celui-ci, il sera facile à utiliser

# frozen_string_literal: true

require 'redis'

module FluentdLogHelper

  def fetch_fluentd_log_by(tag:, pid: nil)
    redis_key = pid ? "#{tag}.#{pid}" : tag
    redis.zrange redis_key, 0, -1
  end

  def redis(options = {})
    options[:db] ||= 0
    @redis ||= Redis.new(options)
  end

end

Nom simple


fetch_fluentd_log_by tag: 'debug.test'

Appeler avec l'identifiant de processus


fetch_fluentd_log_by tag: 'debug.test', pid: Process.pid

Recommended Posts

Créer un serveur fluentd pour les tests
[Android] Créez une validation pour la saisie de la date!
Créez votre propre encodage pour String.getBytes ()
Créer un serveur fluentd pour les tests
Comment créer un référentiel Maven pour 2020
Comment créer une base de données H2 n'importe où
Comment créer des pages pour le tableau "kaminari"
[Java] Créons un Minecraft Mod 1.16.1 [Introduction]
[Java] Créons un Minecraft Mod 1.14.4 [99. Mod output]
Créer un serveur API Web avec Spring Boot
Créer un environnement Docker pour Oracle 11g XE
[Java] Créons un Minecraft Mod 1.14.4 [0. Fichier de base]
[Java] Créons un Minecraft Mod 1.14.4 [4. Ajouter des outils]
Créer un conteneur Docker pour un serveur Web simple Python
Créez un serveur de fichiers HTTPS pour le développement avec ring-jetty-adapter
[Java] Créer un filtre
[Java] Créons un Minecraft Mod 1.14.4 [5. Ajouter une armure]
[Java] Créons un Minecraft Mod 1.14.4 [édition supplémentaire]
[Java] Créons un Minecraft Mod 1.14.4 [7. Add progress]
[Java] Créons un Minecraft Mod 1.14.4 [6. Ajouter une recette]
Créez un modèle pour le widget iOS14 avec la configuration d'intention.
[Java] Créons un Minecraft Mod 1.16.1 [Fichier de base]
[Java] Créons un Minecraft Mod 1.14.4 [1. Ajouter un élément]
Essayez Easy Ramdom, un outil de test PropertyBase pour Java
[Java] Créons un Minecraft Mod 1.14.4 [2. Ajouter un bloc]
Je souhaite créer une annotation générique pour un type
[Java] Créons un Minecraft Mod 1.16.1 [Ajouter un bloc]
Tutoriel pour créer un blog avec Rails pour les débutants Partie 1
Comment créer une image de conteneur légère pour les applications Java
[Java twig] Créer un combinateur d'analyseur pour l'analyse syntaxique de descente récursive
Enfin, créez une méthode pour savoir s'il y a un caractère
Tutoriel pour créer un blog avec Rails pour les débutants Partie 2
Comment créer et lancer un Dockerfile pour Payara Micro
Créer une méthode java [Memo] [java11]
[Java] Créer un fichier temporaire
Créez un plugin VSCode.
Créez un terrain de jeu avec Xcode 12
Créer une loterie avec Ruby
Comment créer une méthode
Créez un serveur Web simple avec la bibliothèque standard Java com.sun.net.httpserver
[Java] Créons un Minecraft Mod 1.16.1 [Ajouter et générer des arbres]
[Java] Créons un Minecraft Mod 1.14.4 [9. Ajouter et générer des arbres]
Comment créer un serveur Web sur une instance EC2 d'AWS
Créez une image Docker pour redoc-cli et enregistrez-la sur Docker Hub
[Java] Créons un Minecraft Mod 1.14.4 [8. Ajouter et générer du minerai]