Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue importing HttpService #437

Open
peisenmann opened this issue Feb 3, 2023 · 8 comments
Open

Issue importing HttpService #437

peisenmann opened this issue Feb 3, 2023 · 8 comments

Comments

@peisenmann
Copy link

peisenmann commented Feb 3, 2023

In the @next/axios code, they do a bunch of setup for the AXIOS_INSTANCE_TOKEN, but I don't see the same setup in the in the tracing module

Nest is throwing this error:

[Nest] 11754  - 02/02/2023, 10:15:02 PM   ERROR [ExceptionHandler] Nest can't resolve dependencies of the HttpService (?). Please make sure that the argument AXIOS_INSTANCE_TOKEN at index [0] is available in the HttpTracingModule context.

Potential solutions:
- If AXIOS_INSTANCE_TOKEN is a provider, is it part of the current HttpTracingModule?
- If AXIOS_INSTANCE_TOKEN is exported from a separate @Module, is that module imported within HttpTracingModule?
  @Module({
    imports: [ /* the Module containing AXIOS_INSTANCE_TOKEN */ ]
  })

Error: Nest can't resolve dependencies of the HttpService (?). Please make sure that the argument AXIOS_INSTANCE_TOKEN at index [0] is available in the HttpTracingModule context.

Potential solutions:
- If AXIOS_INSTANCE_TOKEN is a provider, is it part of the current HttpTracingModule?
- If AXIOS_INSTANCE_TOKEN is exported from a separate @Module, is that module imported within HttpTracingModule?
  @Module({
    imports: [ /* the Module containing AXIOS_INSTANCE_TOKEN */ ]
  })

Dependencies from package.json:
"@narando/nest-xray": "^2.1.0",
"@nestjs/axios": "0.1.0",
"@nestjs/common": "^9.3.1",
"@nestjs/config": "^2.3.0",
"@nestjs/core": "^9.3.1",
"@nestjs/event-emitter": "^1.4.1",
"@nestjs/jwt": "^10.0.1",
"@nestjs/passport": "^9.0.1",
"@nestjs/platform-express": "^9.3.1",
"@nestjs/platform-ws": "^9.3.1",
"@nestjs/schedule": "^2.1.0",
"@nestjs/websockets": "^9.3.1",
"axios": "0.27.2",

@peisenmann
Copy link
Author

I went ahead and did a patch-package to get me through. I would put in a PR, but I didn't test thoroughly enough yet.

index 63d8d9d..4be8c41 100644
--- a/node_modules/@narando/nest-xray/dist/clients/http/http-tracing.module.js
+++ b/node_modules/@narando/nest-xray/dist/clients/http/http-tracing.module.js
@@ -9,17 +9,30 @@ var HttpTracingModule_1;
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.HttpTracingModule = void 0;
 const axios_1 = require("@nestjs/axios");
+const axios_2 = __importDefault(require("axios"));
 const common_1 = require("@nestjs/common");
 const tracing_axios_interceptor_1 = require("./tracing.axios-interceptor");
 let HttpTracingModule = HttpTracingModule_1 = class HttpTracingModule {
+    static register(config) {
+        const httpModule = axios_1.HttpModule.register(options);
+        return Object.assign(Object.assign({}, httpModule), { module: HttpTracingModule_1 });
+    }
+
     static registerAsync(options) {
         const httpModule = axios_1.HttpModule.registerAsync(options);
         return Object.assign(Object.assign({}, httpModule), { module: HttpTracingModule_1 });
     }
 };
+
 HttpTracingModule = HttpTracingModule_1 = __decorate([
     (0, common_1.Module)({
-        providers: [axios_1.HttpService, tracing_axios_interceptor_1.TracingAxiosInterceptor],
+        providers: [
+            {
+                provide: "AXIOS_INSTANCE_TOKEN",
+                useValue: axios_2.default,
+            },
+            axios_1.HttpService, tracing_axios_interceptor_1.TracingAxiosInterceptor,
+        ],
         exports: [axios_1.HttpService],
     })
 ], HttpTracingModule);

This issue body was partially generated by patch-package.

@peisenmann
Copy link
Author

Unfortunately, even after this, I wasn't able to get traces to actually show up in XRay, so I've moved to OpenTelemetry's libraries to see if I can make that work instead.

@vahahavronsky
Copy link

vahahavronsky commented Jul 14, 2023

@peisenmann hey, how are things going with XRay? Please lemme know what is your solution to the whole xray in nest.js problem? Will be very grateful!

@vhavronsky
Copy link

I've managed to make this work by workaround:

    HttpTracingModule.registerAsync({ useFactory: () => ({}) }),

@peisenmann
Copy link
Author

@peisenmann hey, how are things going with XRay? Please lemme know what is your solution to the whole xray in nest.js problem? Will be very grateful!

@vhavronsky Apologies that I missed this notification. Honestly and disappointingly, I was never able to get any form of telemetry working. I tried this package. I tried integrating OpenTelemetry. I believe I followed all the steps, and I was seeing telemetry logged to the console, but when I tried to get it to export to XRay, nothing I did seemed to help. At this point, I've rolled back all my attempts and abandoned the effort, relying on simple nginx timings in the access log and SQL timing via 3rd party DB integrated monitoring. I would love to revisit this in the future as it seems it should be a no-brainer with Nest's architecture, but I failed to get it working and had to move on.

@vhavronsky
Copy link

@peisenmann We've actually made XRay work just fine. You have to:

  • explicitly set the AWS_XRAY_DAEMON_ADDRESS to 172.17.0.1:2000
  • and set up the Daemon. We are using EC2 & ECS so we just had to add an XRay Daemon as a Cluster's Service. I believe here's a relevant Terraform code:
########################################################################################
####################################### X - Ray ########################################
########################################################################################

########################################################################################
## X Ray Sampling rules
########################################################################################

# TO DO
# TO DO
# TO DO

########################################################################################
## IAM (ECS Task Role)
########################################################################################

resource "aws_iam_policy" "xray_policy" {
  name = "xray-policy"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "xray:PutTraceSegments",
          "xray:PutTelemetryRecords",
          "xray:GetSamplingRules",
          "xray:GetSamplingTargets",
          "xray:GetSamplingStatisticSummaries",
          "xray:GetTraceGraph",
          "xray:GetTraceSummaries",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}

resource "aws_iam_role" "ecs_xray_role" {
  name = "ecs-xray-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ecs-tasks.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "xray" {
  policy_arn = aws_iam_policy.xray_policy.arn
  role       = aws_iam_role.ecs_xray_role.name
}

########################################################################################
## IAM (ECS Task Execution Role)
########################################################################################

resource "aws_iam_policy" "xray_execution_role_policy" {
  name = "xray-execution-role-policy"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "ecr:GetAuthorizationToken",
          "ecr:BatchCheckLayerAvailability",
          "ecr:GetDownloadUrlForLayer",
          "ecr:BatchGetImage",
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents",
          "logs:DescribeLogStreams",
          "ssm:GetParameters",
          "kms:GenerateDataKey",
          "kms:Encrypt",
          "kms:Decrypt",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}

resource "aws_iam_role" "ecs_xray_execution_role" {
  name = "ecs-xray-execution-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ecs-tasks.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "xray_execution" {
  policy_arn = aws_iam_policy.xray_execution_role_policy.arn
  role       = aws_iam_role.ecs_xray_execution_role.name
}

########################################################################################
## ECS Task Definition
########################################################################################

resource "aws_ecs_task_definition" "xray" {
  task_role_arn      = aws_iam_role.ecs_xray_role.arn
  execution_role_arn = aws_iam_role.ecs_xray_execution_role.arn
  family             = "xray"
  network_mode       = "host"
  container_definitions = jsonencode([
    {
      name              = "xray_daemon"
      image             = "public.ecr.aws/xray/aws-xray-daemon:latest"
      cpu               = 25
      memoryReservation = 50
      containerPort     = 2000
      protocol          = "udp"
      portMappings = [
        {
          "hostPort" : 2000,
          "containerPort" : 2000,
          "protocol" : "udp"
        }
      ],

      # # Uncomment to enable logging
      # logConfiguration = {
      #       logDriver =  "awslogs",
      #       options = {
      #           awslogs-group = "xray",
      #           awslogs-region = "eu-west-2",
      #           awslogs-create-group = "true"
      #       }
      #   },
    },
  ])
}

########################################################################################
## ECS Services
########################################################################################


resource "aws_ecs_service" "xray" {
  name                 = "xray"
  cluster              = data.aws_ecs_cluster.octo.arn
  task_definition      = aws_ecs_task_definition.xray.arn
  desired_count        = "1"
  scheduling_strategy  = "DAEMON"
  force_new_deployment = true
}

resource "aws_ecs_service" "xray_admin" {
  name                 = "xray"
  cluster              = data.aws_ecs_cluster.octo_admin.arn
  task_definition      = aws_ecs_task_definition.xray.arn
  desired_count        = "1"
  scheduling_strategy  = "DAEMON"
  force_new_deployment = true
}

@peisenmann
Copy link
Author

@peisenmann We've actually made XRay work just fine. You have to:

* explicitly set the `AWS_XRAY_DAEMON_ADDRESS` to `172.17.0.1:2000`

* and set up the Daemon. We are using EC2 & ECS so we just had to add an XRay Daemon as a Cluster's Service. I believe here's a relevant Terraform code: ...

That's interesting. I'm using Elastic Beanstalk at the moment, though perhaps I could take the same Terraform approach. I don't know that I ever attempted setting the AWS_XRAY_DAEMON_ADDRESS, so perhaps with the Beanstalk built in Xray Daemon, that might simply work.

I'm heavily tasked on other products at the moment, but I'll try to get back to that one and test out this concept when I can. Thanks!

@mohitphrasee
Copy link

 HttpTracingModule.registerAsync({ useFactory: () => ({}) }),

Where should I add this line? I used TracingModule instead of axios client, but I'm getting errors as mentioned in the original issue above. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants