Maison >développement back-end >Golang >Réutiliser le client de journalisation dans l'intercepteur de la méthode du serveur Golang grpc

Réutiliser le client de journalisation dans l'intercepteur de la méthode du serveur Golang grpc

PHPz
PHPzavant
2024-02-06 09:03:12424parcourir

在 Golang grpc 服务器方法的拦截器中重用日志客户端

Contenu de la question

Je construis un serveur grpc en utilisant go. Actuellement le serveur propose trois méthodes :

  • Soumettez votre mission
  • Annuler le travail
  • Obtenir le statut de l'emploi

J'utilise datadog pour enregistrer certaines métriques telles que le nombre de demandes, la durée, etc. La méthode submitjob ressemble à ceci :

func (s *myserver) submitjob(ctx context.context, request *submitjobrequest) (*submitjobresponse, error) {
        s.dd_client.logrequestcount("submitjob")
        start_time := time.now()
        defer s.dd_client.logrequestduration("submitjob", time.since(start_time))

        resp := somefunc()

    return resp, nil
}

Le code de journalisation dans ces trois méthodes de serveur différentes est presque identique. Je veux donc savoir comment éviter cette duplication.

J'ai remarqué que golang grpc a le concept d'intercepteurs. Fondamentalement, je peux définir une fonction d'intercepteur et l'utiliser pour effectuer le pré/post-traitement des appels de méthode serveur.

Suite à la documentation, j'ai écrit un intercepteur comme suit :

func unaryInterceptor(ctx context.Context,
    req interface{},
    info *grpc.UnaryServerInfo,
    handler grpc.UnaryHandler,
) (interface{}, error) {
    dd_client := NewDatadogClient()
    defer dd_client.Close()

        dd_client.LogRequestCount(info.FullMethod)

        start_time := time.Now()

    resp, err := handler(ctx, req)

        dd_client.LogRequestDuration(info.FullMethod, time.Since(start_time))

    return resp, err
}

Le problème est qu'à chaque fois que l'intercepteur est appelé, il crée et détruit un nouveau client datadog. Je pense que c'est inutile. Mais comme unaryinterceptor n'est qu'une méthode et non une classe, je ne vois pas de moyen de créer le client datadog une fois et de le réutiliser plus tard ? Existe-t-il un moyen de répondre à mes besoins ?


Bonne réponse


Oui, ne le créez pas sur place, mais déplacez-le vers un autre fichier/package, appelons-le datadog.go

Vous devez le déclarer comme singleton pour qu'il n'ait qu'un seul pointeur dans toutes les utilisations comme...

(J'utilise le type "datadogtype" pour faire référence au type de données renvoyé par la fonction "newdatadogclient", merci de préciser le package et la version pour donner un exemple de code plus précis)

//your package code....


var dataDog DataDogType

//access it through a wrapper, the wrapper will init the var the first time, 
//the remaining times it will be reused

func GetDataDog()(*DataDogType) {

if dataDog == nil {
    dataDog = NewDatadogClient()
}


return dataDog

}

Maintenant, selon votre cas d'utilisation, si vous le renvoyez sous forme de pointeur et le fermez, vous en fermerez toutes les utilisations, donc renvoyez le pointeur lui-même et omettez la partie qui le ferme, ou renvoyez la valeur, c'est donc une copie de l'original

BTW, pouvez-vous partager la version de Datadog et le package spécifique que vous utilisez ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer