Tout le monde, lorsque vous créez une application, crachez-vous les journaux sur le stockage sur le serveur d'applications? ??
Dans GAE / go (environnement standard), si vous utilisez google.golang.org / appengine / log
, il sera affiché dans la visionneuse de journal, vous pouvez facilement filtrer le journal, etc.," What a wonderful !! " Je pense que j'ai été impressionné.
Cependant, GAE / FE n'a pas généré de sortie vers la visionneuse de journal sans rien faire.
J'ai eu beaucoup de problèmes et j'ai pu sortir comme prévu, donc je vais l'écrire en détail car cela peut être utile pour quelqu'un un jour, y compris diverses enquêtes.
La première méthode de sortie de journal à laquelle j'ai pensé était d'utiliser l'API StackDriver Logging (v2) moi-même. → ici
Lors de l'utilisation de cette méthode, il est nécessaire de trier la destination de sortie (destination de connexion API) lors de la frappe dans l'environnement de développement local, de la frappe dans l'environnement de préparation, de la frappe dans l'environnement de production et d'une demande Puisqu'il n'est pas bon de frapper l'API plusieurs fois avec, il semble nécessaire de créer un mécanisme pour tamponner l'écriture dans la portée de la requête et exécuter l'API de journalisation.
Dans une telle situation, fluentd s'exécute dans l'environnement FE, et j'ai eu l'information que le fichier craché dans le format approprié est sorti vers la visionneuse de journal dans le format approprié, et la stratégie de sortie de journal va immédiatement à la deuxième génération.
`Pour connecter votre application d'environnement flexible App Engine à Stackdriver Error Reporting, envoyez des données structurées dans un fichier journal personnalisé. ''
ʻL'agent Stackdriver Logging est installé et configuré par défaut dans l'application App Engine Flexible Environment. ''
https://cloud.google.com/error-reporting/docs/setup/app-engine-flexible-environment
Je vois, j'en suis reconnaissant. Selon les informations, en sortant vers un fichier fixe dans un format fixe, vous pouvez le collecter correctement. Quand.
Je comprends qu'il existe un mécanisme de sortie, mais je ne connais pas la destination de sortie et la forme du JSON à sortir ...
J'ai fait référence à des documents tels que Utilisation de la journalisation cloud dans les applications App Engine, mais cela ne fonctionne pas subtilement.
N'est-il pas plus rapide d'abandonner le document à partir de ce moment et d'étudier régulièrement le code source et l'environnement? J'ai ressenti cela, alors je suis passé à cette méthode.
Tout d'abord, saisissez l'environnement tout en examinant le référentiel de paramètres autour du conteneur de l'environnement FE appelé Managed VM Sidecar Containers.
Écrivez le code → déployez → attendez jusqu'à ce que vous réalisiez que vous pouvez vous connecter à ssh. C'était une pénitence, mais si vous pouvez vous connecter, celle-ci. Je vais enquêter sur diverses choses.
Cliquez sur «Instance» d'appengine puis sur «SSH» de l'instance pour lancer le terminal sur le navigateur.
La destination connectée par le terminal sera une instance de l'environnement FE. (C'est peut-être une instance GCE?) Vérifions le conteneur en cours d'exécution avec la commande suivante.
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
61096f77d1a5 gcr.io/google_appengine/nginx-proxy "/var/lib/nginx/bin/s" About an hour ago Up About an hour 8080/tcp, 8090/tcp, 0.0.0.0:8443->8443/tcp thirsty_brattain
3e176f20673a us.gcr.io/fe-stud/appengine/default.20161206t152342@sha256:330d6b553033c80ad0313fe3c2fd713bdaec873197d00193b6f8a32beda0ca73 "/docker-entrypoint.b" About an hour ago Up About an hour 8080/tcp gaeapp
73675d907c83 gcr.io/google_appengine/api-proxy "/proxy" About an hour ago Up About an hour api
5430f456d28c gcr.io/google_appengine/fluentd-logger "/opt/google-fluentd/" About an hour ago Up About an hour stupefied_heisenberg
L'instance d'environnement FE a quatre conteneurs s'exécutant sur Docker, et il semble que le conteneur fluentd récupère et envoie le journal lorsque le journal est craché depuis le gaeapp (application) vers le répertoire d'instance hôte partagé.
Comme il est fluide, le fichier journal à collecter est défini dans File in Github.
/fluentd_logger/managed_vms.conf
C'est comme suit.
Modèle de fichier |
---|
/var/log/app_engine/app/app*.log |
/var/log/app_engine/app/app*.json |
/var/log/app_engine/app/request*.log |
/var/log/app_engine/app/STDOUT*.log |
/var/log/app_engine/app/STDERR*.log |
/var/log/app_engine/app/custom_logs/*.log |
/var/log/app_engine/app/custom_logs/*.json |
/var/log/app_engine/monitoring/*.log |
/var/log/syslog |
Je me demande si c'est l'objectif standard. Notez que c'est le chemin à l'intérieur du conteneur fluentd! (J'étais un peu accro à la croyance que le même chemin serait dans le conteneur gaeapp ...)
Voici comment je suis devenu accro. Table de correspondance des chemins de répertoire
Le chemin que le conteneur gaeapp monte | Répertoire de journal dans l'instance d'hôte | Chemin monté par conteneur fluentd |
---|---|---|
/var/log/app_engine | /var/log/app_engine/app | /var/log/app_engine/app |
As-tu remarqué? Oui, le chemin du répertoire du journal de l'instance hôte et le conteneur de fluentd sont identiques, mais pour une raison quelconque, le chemin du répertoire du journal de gaeapp est différent. .. ..
Donc, même si je regarde le fichier de paramètres fluentd et que je sort le fichier journal dans gaeapp pour ce répertoire, fluentd ne le récupère pas ... (larmes.
Je pense que c'est une bonne idée de mettre cette zone dans un conteneur fluide et de l'essayer tout en suivant le journal.
Pour entrer dans le conteneur fluentd sur l'instance hôte
$ sudo docker exec -it stupefied_heisenberg bash
Entrez dans le conteneur avec
# tail -f /var/log/google-fluentd/google-fluentd.log
Vous pouvez le voir sur. Au fait, si le journal est correctement récupéré par fluentd
2016-12-06 07:47:25 +0000 [info]: following tail of /var/log/app_engine/app/app.json
2016-12-06 07:54:25 +0000 [info]: following tail of /var/log/app_engine/app/app.log.json
Un journal comme celui-ci est généré. (Notez qu'il n'est sorti que la première fois que le fichier est trouvé.)
Les journaux de texte sont générés sous forme de texte lors de la sortie dans un fichier avec l'extension * .log
.
Ce qui diffère du journal au format JSON, c'est que des informations telles que le niveau de journal ne peuvent pas être ajoutées.
Exemple de sortie app.log Désolé pour l'image allongée. .. Lors de la sortie sous forme de texte (le contenu est au format JSON dans l'exemple), il est sorti sans le niveau de journalisation (icône à gauche).
Je veux toujours le niveau de journalisation lors de la sortie de l'application. Par conséquent, le format JSON requis pour la sortie est indiqué ci-dessous.
Utilisez JsonFormatter.java
et LogContext.java
dans appengine-java-vm-runtime pour formater le JSON. ..
Même lorsque vous l'utilisez dans d'autres langues, la méthode de format dans JsonFormatter.java
n'effectue pas un traitement aussi difficile, donc je pense que vous pouvez l'implémenter en vous référant à cela.
Ainsi, la conclusion est l'exemple de format JSON, qui se présente comme suit.
{
"timestamp":{"seconds":1481005920,"nanos":927000000},
"severity":"ERROR",
"thread":"qtp1347137144-13",
"message":"TestLogger: === TEST LOG ==="
}
Au fait, lorsque vous utilisez le précédent JsonFormatter
, vous utiliserez java.util.logging.LogRecord
, mais en guise de mise en garde, vous devez entrer le nom de l'enregistreur en utilisant LogRecord # setLoggerName
.
Cela ne cause pas d'erreur même si je ne le saisis pas, mais le message JSON ressemble à `" null: === TEST LOG === "ʻet ce n'est pas cool.
Exemple de code approximatif
Level level = Level.SEVERE; //Niveau de journal, équivalent à Erreur
LogRecord record = new LogRecord(level, "=== TEST LOG ===");
record.setLoggerName("TestLogger");
JsonFormatter formatter = new JsonFormatter();
String logString = formatter.format(record); //Vous pouvez afficher cette chaîne sous forme de ligne dans le fichier json.
Si vous pouvez vous préparer jusqu'à présent, vous pourrez cracher du JSON dans un fichier et le sortir proprement dans la visionneuse de journal. L'exemple est affiché au niveau d'erreur, il y a donc une icône qui ne semble pas être juste une chose [! !! ]
Lors de l'utilisation avec Scala (Java), je voudrais sortir en utilisant slf4j / logback etc., mais j'ai pu sortir par la méthode suivante.
et ʻappengine-managed-runtime
au projet pom.xml
pom.xml
<!-- https://mvnrepository.com/artifact/com.google.appengine/appengine-java-logging -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-java-logging</artifactId>
<version>1.9.31</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.appengine/appengine-managed-runtime -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-managed-runtime</artifactId>
<version>1.9.31</version>
</dependency>
VmRuntimeFileLogHandler # init
quelque part dans votre application.Cela spécifie en interne les paramètres de sortie du journal.
VmRuntimeFileLogHandler.java
// ~~ snip ~~
private static String fileLogPattern() {
String pattern = System.getenv("APP_ENGINE_LOG_CONFIG_PATTERN");
if(pattern != null) {
return pattern;
} else {
String directory = System.getProperty("com.google.apphosting.logs", "/var/log/app_engine");
pattern = System.getProperty("com.google.apphosting.vmruntime.VmRuntimeFileLogHandler.pattern");
return pattern != null?(pattern.startsWith("/")?pattern:directory + "/" + pattern):directory + "/" + "app.%g.log.json";
}
}
// ~~ snip ~~
Vous pouvez publier le contenu spécifié dans logback.xml
etc. en vous référant à cette classe. Dans ce cas, vous n'avez pas besoin d'appeler VmRuntimeFileLogHandler # init
.
LogSample.java
Logger logger = Logger.getLogger("com"); //Génération d'enregistreurs
logger.warning("= WARNING TEST ="); //Sortie de journal
logging.properties
selon vos besoins.level=ALL
com.level=SEVERE
Nous tenons à remercier @soundTricker pour nous avoir fourni diverses informations et consultations concernant la sortie des journaux dans l'environnement FE.
Recommended Posts