func main()

in Elastiflix/go-favorite-otel-manual/main.go [133:282]


func main() {
	delayTime, _ := strconv.Atoi(os.Getenv("TOGGLE_SERVICE_DELAY"))

	cleanup := initTracer()
    defer cleanup(context.Background())


	redisHost := os.Getenv("REDIS_HOST")
	if redisHost == "" {
		redisHost = "localhost"
	}

	redisPort := os.Getenv("REDIS_PORT")
	if redisPort == "" {
		redisPort = "6379"
	}

	applicationPort := os.Getenv("APPLICATION_PORT")
	if applicationPort == "" {
		applicationPort = "5000"
	}

	// Initialize Redis client
	rdb := redis.NewClient(&redis.Options{
		Addr:     redisHost + ":" + redisPort,
		Password: "",
		DB:       0,
	})
	rdb.AddHook(redisotel.NewTracingHook())


	// Initialize router
	r := gin.New()
	r.Use(logrusMiddleware)
	r.Use(otelgin.Middleware("go-favorite-otel-manual"))

	
	// Define routes
	r.GET("/", func(c *gin.Context) {
		contextLogger(c).Infof("Main request successful")
		c.String(http.StatusOK, "Hello World!")
	})

	r.GET("/favorites", func(c *gin.Context) {
		// artificial sleep for delayTime
		time.Sleep(time.Duration(delayTime) * time.Millisecond)
		
		userID := c.Query("user_id")

		contextLogger(c).Infof("Getting favorites for user %q", userID)

		favorites, err := rdb.SMembers(c.Request.Context(), userID).Result()
		if err != nil {
			contextLogger(c).Error("Failed to get favorites for user %q", userID)
			c.String(http.StatusInternalServerError, "Failed to get favorites")
			return
		}

		contextLogger(c).Infof("User %q has favorites %q", userID, favorites)

		c.JSON(http.StatusOK, gin.H{
			"favorites": favorites,
		})
	})

	r.POST("/favorites", func(c *gin.Context) {
		// start otel span
		ctx := c.Request.Context()
		ctx, span := tracer.Start(ctx, "add_favorite_movies")
		defer span.End()

		// artificial sleep for delayTime
		time.Sleep(time.Duration(delayTime) * time.Millisecond)
		
		userID := c.Query("user_id")

		contextLogger(c).Infof("Adding or removing favorites for user %q", userID)

		var data struct {
			ID int `json:"id"`
		}
		if err := c.BindJSON(&data); err != nil {
			contextLogger(c).Error("Failed to decode request body for user %q", userID)
			c.String(http.StatusBadRequest, "Failed to decode request body")
			return
		}

		redisResponse := rdb.SRem(c.Request.Context(), userID, data.ID)
		if redisResponse.Err() != nil {
			contextLogger(c).Error("Failed to remove movie from favorites for user %q", userID)
			c.String(http.StatusInternalServerError, "Failed to remove movie from favorites")
			return
		}

		if redisResponse.Val() == 0 {
			rdb.SAdd(c.Request.Context(), userID, data.ID)
		}

		favorites, err := rdb.SMembers(c.Request.Context(), userID).Result()
		contextLogger(c).Infof("Getting favorites for user")
		if err != nil {
			contextLogger(c).Error("Failed to get favorites for user %q", userID)
			c.String(http.StatusInternalServerError, "Failed to get favorites")
			return
		}

		contextLogger(c).Infof("User %q has favorites %q", userID, favorites)

		// if enabled, in 50% of the cases, sleep for 2 seconds
		sleepTimeStr := os.Getenv("TOGGLE_CANARY_DELAY")
		sleepTime := 0
		if sleepTimeStr != "" {
			sleepTime, _ = strconv.Atoi(sleepTimeStr)
		}

		if sleepTime > 0 && rand.Float64() < 0.5 {
			time.Sleep(time.Duration(rand.NormFloat64()*float64(sleepTime / 10)+float64(sleepTime))* time.Millisecond)
			// add label to transaction
			logger.Info("Canary enabled")


			span := trace.SpanFromContext(c.Request.Context())
			span.SetAttributes(attribute.String("quiz_solution", "correlations"))
			span.SetAttributes(attribute.String("canary", "test-new-feature"))

			// read env var TOGGLE_CANARY_FAILURE, which is a float between 0 and 1
			if toggleCanaryFailureStr := os.Getenv("TOGGLE_CANARY_FAILURE"); toggleCanaryFailureStr != "" {
				toggleCanaryFailure, err := strconv.ParseFloat(toggleCanaryFailureStr, 64)
				if err != nil {
					toggleCanaryFailure = 0
				}
				if rand.Float64() < toggleCanaryFailure {
					// throw an exception in 50% of the cases
					span.SetStatus(codes.Error, "Something went wrong")
					logger.Error("Something went wrong")
					panic("Something went wrong")
				}
			}
		}

		c.JSON(http.StatusOK, gin.H{
			"favorites": favorites,
		})
	})

	// Start server
	logger.Infof("App startup")
	log.Fatal(http.ListenAndServe(":"+applicationPort, r))
	logger.Infof("App stopped")
}