Giter VIP home page Giter VIP logo

serverless-lumigo-plugin's Introduction

serverless-lumigo

CircleCI serverless version License codecov

Serverless framework plugin to auto-install the Lumigo tracer for Node.js and Python functions.

TOC

Install

Run npm install in your Serverless project.

$ npm install --save-dev serverless-lumigo

Add the plugin to your serverless.yml file

plugins:
  - serverless-lumigo

Node.js functions

For Node.js functions, the plugin would install the latest version of the Lumigo tracer for Node.js during serverless package and serverless deploy. It would also wrap your functions as well, so you only need to configure your Lumigo token in a custom section inside the serverless.yml.

For example:

provider:
  name: aws
  runtime: nodejs12.x

custom:
  lumigo:
    token: <YOUR TOKEN GOES HERE>
    nodePackageManager: <npm, pnpm or yarn>

In case you want to pin the specific tracer version use pinVersion attribute.

For example

provider:
  name: aws
  runtime: nodejs12.x

custom:
  lumigo:
    token: <YOUR TOKEN GOES HERE>
    pinVersion: 1.31.1

In case you want to manage the Lumigo tracer dependency yourself - e.g. you want to use Lerna or Webpack, and can't have this plugin install the Lumigo tracer on your behalf on every deployment - then you can also disable the NPM install process altogether.

provider:
  name: aws
  runtime: nodejs12.x

custom:
  lumigo:
    token: <YOUR TOKEN GOES HERE>
    skipInstallNodeTracer: true # defaults to false

In case you are using ES Modules for Lambda handlers.

provider:
  name: aws
  runtime: nodejs14.x

custom:
  lumigo:
    token: <YOUR TOKEN GOES HERE>
    nodeUseESModule: true
    nodeModuleFileExtension: js

Python functions

For Python functions, we recommend using the serverless-python-requirements plugin to help you manage your dependencies. You should have the following in your requirements.txt:

lumigo_tracer or lumigo-tracer

This installs the Lumigo tracer for Python, and this plugin would wrap your functions during serverless package and serverless deploy.

You also need to configure the Lumigo token in a custom section in the serverless.yml.

provider:
  name: aws
  runtime: python3.10
custom:
  lumigo:
    token: <YOUR TOKEN GOES HERE>

In case you are not using requirements.txt to manage your requirements then you can add skipReqCheck and set it to true

custom:
  lumigo:
    token: 1234
    skipReqCheck: true

Configuration

In order to pass parameters to the tracer, just add them as keys to lumigo custom configuration. For example:

custom:
  lumigo:
    token: <YOUR TOKEN GOES HERE>
    step_function: true

Function Scope Configuration

You can configure lumigo behavior for individual functions as well:

  • enabled - Allows one to enable or disable lumigo for specific a specific function

    functions:
      foo:
        lumigo:
          enabled: false
    
      bar:
        lumigo:
          enabled: ${self:custom.enabledLumigo}

How to test

Run npm run test:all

serverless-lumigo-plugin's People

Contributors

dependabot[bot] avatar doriaviram avatar efimk-lu avatar guymoses avatar kjartanm avatar mzl-md avatar nadav3396 avatar nirlumigo avatar roni-frantchi avatar saartochner-lumigo avatar theburningmonk avatar therightstuff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serverless-lumigo-plugin's Issues

Serverless-bundle compatibility

Hello. I have a serverless app written in Typescript and compiled using serverless-bundle.

Seems there's a compatibility issue between lumigo and serverless-bundle. When trying to deploy:

  • first, lumigo wraps my typescript files, turning them into js files
> sls deploy --stage $SLS_ENV

Deploying enkicamp-hydra to stage staging (*********)
serverless-lumigo: there are 86 function(s) to wrap...
serverless-lumigo: {"name":"enkicamp-hydra-staging-healthcheck","description":"endpoint to serve as an API healthcheck","handler":"functions/common/api/healthcheck/index.handler","events":[{"http":{"method":"get","path":"/healthcheck","cors":true}}],"localName":"healthcheck"}
...
serverless-lumigo: installing @lumigo/tracer@latest...
serverless-lumigo: 
up to date, audited 2510 packages in 7s

234 packages are looking for funding
 run `npm fund` for details

27 vulnerabilities (13 low, 4 moderate, 9 high, 1 critical)

To address issues that do not require attention, run:
 npm audit fix

To address all issues possible (including breaking changes), run:
 npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

serverless-lumigo: wrapping [functions/common/api/healthcheck/index.handler]...
serverless-lumigo: writing wrapper function to [/home/circleci/hydra/_lumigo/healthcheck.js]...
  • second, serverless-bundle runs, trying to compile the typescript
Bundling with Webpack...
=============

WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=3.3.1 <4.5.0

YOUR TYPESCRIPT VERSION: 4.9.5

Please only submit bug reports when using the officially supported version.
webpack compiled with 1 error
ERROR in /home/circleci/hydra/_lumigo/healthcheck.js
  2:16  error  Require statement not part of import statement  @typescript-eslint/no-var-requires
  5:17  error  Require statement not part of import statement  @typescript-eslint/no-var-requires

βœ– 2 problems (2 errors, 0 warnings)

This looks wrong to me. Shouldn't serverless-bundle first bundle compile all ts files, then lumigo wrap them?

Cannot find module '@lumigo/tracer'

Hello, for some reason I'm getting this error in my lambdas:

UserLambdaValidationException: PostConfirmation failed with error Error: Cannot find module '@lumigo/tracer'
    Require stack:
    - /var/task/_lumigo/confirmUserSignup.js
    - /var/runtime/UserFunction.js
    - /var/runtime/Runtime.js
    - /var/runtime/index.js.

My serverless.yml

custom
   lumigo:
      token: ${ssm:/${self:custom.stage}/lumigo-token~true}
      skipInstallNodeTracer: true
      nodePackageManager: yarn

package.json

"devDependencies": {
    "serverless-lumigo": "^1.13.3",
...
},
"dependencies": {
    "@lumigo/tracer": "^1.71.4",
...
}

I wonder if this issue was caused by the fact that I initially integrated lumigo manually, and now I'm integrating it via the the serverless.yml file.

I tried to removed my current project on Lumigo to integrate it via serverless-lumigo but I can't find an option to delete it.

Do you have any idea what's happening?

Why does this plugin require a token while the auto-tracer doesn't?

Hi!

First of all I really like what you're doing! I might be overlooking something but I would like to understand how it works.

I've created the LumigoIntegrationV6 Cloudformation stack in AWS. When using the auto tracer functionality it will automatically connect the lumigo-python-tracer Layer to my Lambda function (I'm using Python).
Using this method, no extra token is required. I assume this uses CF stack (maybe the ExternalId parameter?) to communicate with Lumigo.

When using this plugin, I have to add a token which feels a bit unnecessary. Maybe the LumigoIntegration stack can create a pre-filled, encrypted SSM parameter for the token which then can be used automatically by this plugin?

Function Scope Configuration: unrecognized property 'lumigo'

I recently updated my serverless framework version from 2.10 to 2.68.

Now it gives me the following configuration warning on the function scope configuration property of the lumigo plugin:
Serverless: at 'functions.myFunctionName': unrecognized property 'lumigo'
For a function defined like this:

functions:
  myFunctionName:
    handler: functions/my-function.handler
    lumigo:
      enabled: false

Should I be worried about this?
If so, how can I resolve it?

Using Docker image based lambda raises TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string

It seems to come from

async createWrappedPythonFunction(func, token, options, isZip) {
  this.verboseLog(`wrapping [${func.handler}]...`);
  
  const localName = func.localName;
  
  // e.g. functions/hello.world.handler -> hello.world.handler
  const handler = path.basename(func.handler);
  ...

as no handler is defined in the function, path.basename can't work properly, while it's a valid serverless configuration according to https://www.serverless.com/blog/container-support-for-lambda

ensureLumigoPythonIsInstalled fails, but is listed in requirements.txt

Hi, I want to set up some manual tracing.
I followed the guide.
The lumigo_tracer package is listed in requerments.txt and is installed via pip install -r requirements.txt.
Still deploying with serverless framework does throw this TypeError that sais that Lumigo-Python-Package is not installed.
Are there any additional tweaks to be made?

❯ sls deploy
Serverless: serverless-lumigo: there are 27 function(s) to wrap...
Serverless: serverless-lumigo: checking if lumigo_tracer is installed...

  Type Error ---------------------------------------------

  TypeError: plugins.includes is not a function
      at LumigoPlugin.ensureLumigoPythonIsInstalled (/Users/xxx/sls_plugins/node_modules/serverless-lumigo/src/index.js:329:38)
      at LumigoPlugin.wrapFunctions (/Users/xxx/sls_plugins/node_modules/serverless-lumigo/src/index.js:199:17)
      at LumigoPlugin.afterPackageInitialize (/Users/xxx/sls_plugins/node_modules/serverless-lumigo/src/index.js:71:14)
      at /usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:498:55
      at tryCatcher (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/util.js:16:23)
      at Object.gotValue (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/reduce.js:168:18)
      at Object.gotAccum (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/reduce.js:155:25)
      at Object.tryCatcher (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/util.js:16:23)
      at Promise._settlePromiseFromHandler (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:547:31)
      at Promise._settlePromise (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:604:18)
      at Promise._settlePromise0 (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:649:10)
      at Promise._settlePromises (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:729:18)
      at _drainQueueStep (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:93:12)
      at _drainQueue (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:86:9)
      at Async._drainQueues (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:102:5)
      at Immediate.Async.drainQueues (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:15:14)
      at processImmediate (internal/timers.js:461:21)

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              14.16.1
     Framework Version:         1.83.0
     Plugin Version:            3.8.4
     SDK Version:               2.3.2
     Components Version:        2.34.9

eslint: Trailing spaces not allowed

Webpack + Eslint compilation shows the error below, because the _lumigo folder wrappers have traling spaces at the end of the files.

Can't use plugin unless I disable eslint error.

error:

  8:1  error  Trailing spaces not allowed  no-trailing-spaces

example:
Screenshot from 2020-01-24 20-24-41

Document if the plugin can be used without Lambda Layers

Since it seems – by quickly looking at the source code – that the plugins can use Layers to instrument the code, the README should indicate if the plugins automatically handle cases where we cannot use a layer.

For example, if:

  • A docker is being used, because the dependencies are > 250 MB.
  • The max number of layers is already used.

Support PNPM

PNPM is an alternate package manager to yarn and npm, the most notable of which are generally faster performance and package isolation.

support nodejs14.x runtime

This goes beyond the plugin itself, but it would be great if Lumigo officially supported nodejs14.x runtime

Support for ES6 modules

Since Lambdas now support ES6 modules, it would be nice if this plugin could support that as well. See PR #95.

Plugin won't wrap functions deployed using `sls deploy -f`

Attempting to deploy function will not trigger the plugin.

This causes all sorts of mayhem.

For instance:

  1. Service deployed using sls deploy
  2. Without changing the deployed function code, deploy function sls deploy -f fooBar
  3. Code won't change as Serverless will let us know Serverless: Code not changed. Skipping function deployment.
  4. The handler however will get updated, and will now longer point to _lumigo/fooBar.js but rather mypath/foo-bar.js, and executing the function will fail to execute in runtime because the code does not exist there.

Attaching to the function:deploy lifecycle hook should do the trick.

Opened #24 to resolve this one

_lumigo folder is not included when packaging individually

e.g. given the following serverless.yml

package:
  individually: true
  exclude:
    - "**/*"
  include:
    - functions/**/*

functions:
  handler1:
    handler: functions/handler1/index.hello
    package:
      include:
        - functions/handler1/index.js
        - node_modules/**/*

the wrapped function _lumigo/handler1.js would not be in the packaged zip file

Global Enable Flag

Request to add a global flag to enable / disable Lumigo, so that in temporary / development environments it can be dynamically disabled based on deployment stage.

Example:

custom:
  lumigo:
    token: <YOUR TOKEN GOES HERE>
    skipInstallNodeTracer: true # defaults to false
    enabled: false

Lumigo plugin or tracer appear to swallow lower level error logs

I had an error in my serverless.yml which was to not reference the method, but only the file.

Correct:

functions:
  loadMarketOrders:
    handler: src/jobs/load_market_orders.handle

Wrong:

functions:
  loadMarketOrders:
    handler: src/jobs/load_market_orders

With the lumigo plugin active, I got an error message that seemed to swallow the error and redirected me to the file's line nr. 3 which was an import statement.

START RequestId: e396709d-efac-405a-9bd2-3ec8904da918 Version: $LATEST
[ERROR] Runtime.UserCodeSyntaxError: Syntax error in module '_lumigo/loadMarketOrders': invalid syntax (loadMarketOrders.py, line 3)
Traceback (most recent call last):
Β Β File "/var/task/_lumigo/loadMarketOrders.py" Line 3
Β Β Β Β from  import load_market_orders as userHandler
END RequestId: e396709d-efac-405a-9bd2-3ec8904da918
REPORT RequestId: e396709d-efac-405a-9bd2-3ec8904da918	Duration: 1.97 ms	Billed Duration: 100 ms	Memory Size: 1024 MB	Max Memory Used: 56 MB	Init Duration: 114.16 ms

When I removed the lumigo plugin, the error was a bit more understandable.

START RequestId: 49e38e36-9344-4750-89c9-0ef55f8f9bfd Version: $LATEST
[ERROR] Runtime.MalformedHandlerName: Bad handler 'src/jobs/load_market_orders': not enough values to unpack (expected 2, got 1)
END RequestId: 49e38e36-9344-4750-89c9-0ef55f8f9bfd
REPORT RequestId: 49e38e36-9344-4750-89c9-0ef55f8f9bfd	Duration: 1.51 ms	Billed Duration: 100 ms	Memory Size: 1024 MB	Max Memory Used: 56 MB	Init Duration: 116.08 ms

Suggestion: If possible, don't swallow but print the lower level's error messages.

Notes:

  • serverless 1.51.0
  • python 3.7
  • serverless plugins: serverless-python-requirements and serverless-lumigo

No module named '_lumigo' error when function handler not directly beneath serverless config

I've followed the instructions on the plugin page and am getting an error that there's no such module as _lumigo.

I tried installing a few previous versions and it doesn't look like the lumigo python-tracer package (distributed as lumigo-tracer) has ever shipped this name, so I suspect the problem isn't that the import name has changed, but that the import command is meant to be doing something else.

{                                                                                                                       
    "errorMessage": "Unable to import module '_lumigo/pypi_release_check': No module named '_lumigo'",                  
    "errorType": "Runtime.ImportModuleError",                                                                           
    "requestId": "4d7f20d8-970a-433f-9317-6f504438b5a4",                                                                
    "stackTrace": []                                                                                                    
} 

I suspect the problem may be due to my project structure: I have a serverless.yml and below it I have directories containing Python packages (subservices) deployed in a single service as one stack.

My guess is that this has resulted in the tracer trying to import them from the wrong location.

I haven't read the source closely enough to be sure but if it's looking in the service directory and then assuming to find the service there, i.e. assuming that the handler must be at the top level. In my case the handler is down a level (there's a dotname that goes subpackage.module.funcdef rather than module.funcdef).

I copied the serverless config down a level and adjusted, and packaged there, and can see that when I enable the sls lumigo plugin I get the following code:

import importlib
from lumigo_tracer import lumigo_tracer
userHandler = getattr(importlib.import_module("release_check"), "check_handler")

@lumigo_tracer(token='t_XXXXXXXXXXX')
def check_handler(event, context):
  return userHandler(event, context)

I suspect this would work if the _lumigo directory created in the packaged zip were dropped down a level so that it ends up being within the bounds of where the individual subpackages can "see" (when the Python runtime is invoked on a subpackage it necessarily limits the parent folder which is "visible" to import from, and I think that's what you're relying on here to make the wrapper work).

Annoying because I can see the handler wrapper is right there, hopefully it will be a simple fix ! :-)

For clarity my "subservice" tree below my src directory containing serverless.yml is:

pypi_watcher/
β”œβ”€β”€ functions.yml
β”œβ”€β”€ __init__.py
β”œβ”€β”€ pypi_watcher
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ lookout
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ data_model.py
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ main.py
β”‚Β Β  β”‚Β Β  └── utils
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ __init__.py
β”‚Β Β  β”‚Β Β      └── rss_reader.py
β”‚Β Β  └── release_check.py
β”œβ”€β”€ README.md
β”œβ”€β”€ requirements.txt
└── stepfunctions.yml

and I'm using the functions.yml to define functions for the service above it:

service: ss-python-services

plugins:
  - serverless-python-requirements
  - serverless-lumigo
package:
  individually: true
  # Negated ** include optimises packaging time: further `include`s at function level
  include:
    - "!./**"
  exclude:
    - "**"

custom:
  lumigo:
    token: ${ssm:SS-LUMIGO-TRACING-TOKEN}
    skipReqCheck: true
  pythonRequirements:
    dockerizePip: non-linux
    noDeploy:
      - boto3 # boto3==1.26.90
      - botocore # botocore==1.29.90
      - pytest # pytest==7.1.2
      - pydantic # in layers only
      # https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html

provider:
  name: aws
  runtime: python3.10
  versionFunctions: false
  deploymentBucket: ss-serverless-deployments
  stage: ${opt:stage, 'dev'}
  region: eu-west-1
  timeout: 300
  environment:
    STAGE: ${self:provider.stage}
  iamRoleStatements:
    - Effect: "Allow"
      Action: "secretsmanager:GetSecretValue"
      Resource: "arn:aws:secretsmanager:*"

functions:
  - ${file(../src/pypi_watcher/functions.yml)}

where the functions.yml file contains:

pypi_release_check:
  handler: pypi_watcher.release_check.check_handler
  module: pypi_watcher
  package:
    include:
      - pypi_watcher/pypi_watcher/**
  timeout: 300
  layers:
    - arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:36
  • Note that I un/commented out the package: include/exclude statements here to see if they were involved, this is used to achieve individual package separation in this project layout. I commented it out just to be able to see what was going on. It doesn't affect the result.

When I put the following serverless.yml file in the pypi_watcher directory I could see a _lumigo directory in the packaged zip (specifically the function zip pypi_release_check.zip):

service: pypi-watcher-monoservice

plugins:
  - serverless-python-requirements
  - serverless-lumigo
package:
  individually: true

custom:
  lumigo:
    token: ${ssm:SS-LUMIGO-TRACING-TOKEN}
    skipReqCheck: true
  pythonRequirements:
    dockerizePip: non-linux
    noDeploy:
      - boto3 # boto3==1.26.90
      - botocore # botocore==1.29.90
      - pytest # pytest==7.1.2
      - pydantic # in layers only
      # https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html

provider:
  name: aws
  runtime: python3.10
  versionFunctions: false
  deploymentBucket: ss-serverless-deployments
  stage: ${opt:stage, 'dev'}
  region: eu-west-1
  timeout: 300
  environment:
    STAGE: ${self:provider.stage}
  iamRoleStatements:
    # pypi_watcher
    - Effect: "Allow"
      Action: "secretsmanager:GetSecretValue"
      Resource: "arn:aws:secretsmanager:*"

functions:
  pypi_release_check:
    handler: release_check.check_handler
    module: pypi_watcher
    timeout: 300
    layers:
      - arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:36

Import error when used in combination with zipped python-requirements

Hi,

I just installed the tracer and I noticed that, when adding the zipping option to the 'serverless-python-requirements' plugin my lambdas are raising an ImportError Exception:

{
  "errorMessage": "Unable to import module '_lumigo/DetectDominantLanguageCode': No module named 'lumigo_tracer'",
  "errorType": "Runtime.ImportModuleError"
}

Best,
Javier

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.