Skip to content

Commit

Permalink
Update testing file to use bash script
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanielRN committed Oct 26, 2021
1 parent e4276be commit f5b9cdf
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 32 deletions.
30 changes: 8 additions & 22 deletions python/src/otel/otel_sdk/otel-instrument
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash

# Copyright The OpenTelemetry Authors
#
Expand All @@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

: '
: <<'END_DOCUMENTATION'
`otel-instrument`
This script configures and sets up OpenTelemetry Python with the values we
Expand Down Expand Up @@ -43,7 +43,7 @@ root level of a Lambda Layer:
AWS_LAMBDA_EXEC_WRAPPER = /opt/otel-instrument
'
END_DOCUMENTATION

# Use constants to access the environment variables we want to use in this
# script.
Expand All @@ -68,17 +68,13 @@ root level of a Lambda Layer:
# See more:
# https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path

export LAMBDA_LAYER_PKGS_DIR="/opt/python"
export LAMBDA_LAYER_PKGS_DIR="/opt/python";

# - Set Lambda Layer python packages in PYTHONPATH so `opentelemetry-instrument`
# script can find them (it needs to find `opentelemetry` to find the auto
# instrumentation `run()` method later)

if [ -z ${PYTHONPATH} ]; then
export PYTHONPATH=$LAMBDA_LAYER_PKGS_DIR;
else
export PYTHONPATH="$LAMBDA_LAYER_PKGS_DIR:$PYTHONPATH";
fi
export PYTHONPATH="$LAMBDA_LAYER_PKGS_DIR:$PYTHONPATH";

# - Set Lambda runtime python packages in PYTHONPATH so
# `opentelemetry-instrument` script can find them during auto instrumentation
Expand All @@ -88,11 +84,7 @@ export PYTHONPATH="$LAMBDA_RUNTIME_DIR:$PYTHONPATH";

# Configure OpenTelemetry Python with environment variables

# - Set the default Trace Exporter

if [ -z ${OTEL_TRACES_EXPORTER} ]; then
export OTEL_TRACES_EXPORTER="otlp_proto_grpc_span";
fi
# - Uses the default `OTEL_TRACES_EXPORTER` which is set to `otlp_proto_grpc`

# - Set the service name

Expand All @@ -108,19 +100,15 @@ fi
#
# export OTEL_RESOURCE_DETECTORS="aws_lambda";
#
export LAMBDA_RESOURCE_ATTRIBUTES="cloud.region=$AWS_REGION,cloud.provider=aws,faas.name=$AWS_LAMBDA_FUNCTION_NAME,faas.version=$AWS_LAMBDA_FUNCTION_VERSION"
export LAMBDA_RESOURCE_ATTRIBUTES="cloud.region=$AWS_REGION,cloud.provider=aws,faas.name=$AWS_LAMBDA_FUNCTION_NAME,faas.version=$AWS_LAMBDA_FUNCTION_VERSION";

if [ -z ${OTEL_RESOURCE_ATTRIBUTES} ]; then
export OTEL_RESOURCE_ATTRIBUTES=$LAMBDA_RESOURCE_ATTRIBUTES;
else
export OTEL_RESOURCE_ATTRIBUTES="$LAMBDA_RESOURCE_ATTRIBUTES,$OTEL_RESOURCE_ATTRIBUTES";
fi

# - Set the default propagators

if [ -z ${OTEL_PROPAGATORS} ]; then
export OTEL_PROPAGATORS="tracecontext,b3,xray";
fi
# - Uses the default `OTEL_PROPAGATORS` which is set to `tracecontext,baggage`

# - Use a wrapper because AWS Lambda's `python3 /var/runtime/bootstrap.py` will
# use `imp.load_module` to load the function from the `_HANDLER` environment
Expand All @@ -137,5 +125,3 @@ export _HANDLER="otel_wrapper.lambda_handler";
# - Call the upstream auto instrumentation script

python3 $LAMBDA_LAYER_PKGS_DIR/bin/opentelemetry-instrument "$@"


12 changes: 7 additions & 5 deletions python/src/otel/otel_sdk/otel_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ class HandlerError(Exception):

AwsLambdaInstrumentor().instrument()

path = os.environ.get("ORIG_HANDLER", None)
path = os.environ.get("ORIG_HANDLER")

if path is None:
raise HandlerError("ORIG_HANDLER is not defined.")
parts = path.rsplit(".", 1)
if len(parts) != 2:
raise HandlerError("Value %s for ORIG_HANDLER has invalid format." % path)

(mod_name, handler_name) = parts
try:
(mod_name, handler_name) = path.rsplit(".", 1)
except ValueError as e:
raise HandlerError("Bad path '{}' for ORIG_HANDLER: {}".format(path, str(e)))

modified_mod_name = modify_module_name(mod_name)
handler_module = import_module(modified_mod_name)
lambda_handler = getattr(handler_module, handler_name)
6 changes: 4 additions & 2 deletions python/src/otel/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,7 @@ test =
where = otel_sdk

[options.entry_points]
opentelemetry_instrumentor =
aws_lambda = opentelemetry.instrumentation.aws_lambda:AwsLambdaInstrumentor
# NOTE: (NathanielRN) DO NOT add AwsLambdaInstrumentor entry point because
# current AWS Lambda implementation reloads a fresh import of the user's Lambda
# handler. Auto Instrumentation runs _before_ and if it instruments the handler
# that patching will be lost.
45 changes: 43 additions & 2 deletions python/src/otel/tests/test_otel.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import fileinput
import os
import subprocess
import sys
from importlib import import_module
from shutil import which
from unittest import mock

from opentelemetry.instrumentation.aws_lambda import AwsLambdaInstrumentor
Expand All @@ -33,6 +36,8 @@
INSTRUMENTATION_SRC_DIR = os.path.join(
*(os.path.dirname(__file__), "..", "otel_sdk")
)
ORIG_HANDLER = "ORIG_HANDLER"
TOX_PYTHON_DIRECTORY = os.path.dirname(os.path.dirname(which("python3")))


class MockLambdaContext:
Expand Down Expand Up @@ -67,6 +72,14 @@ def __init__(self, aws_request_id, invoked_function_arn):
MOCK_W3C_TRACE_STATE_VALUE = "test_value"


def replace_in_file(file_path, search_text, new_text):
with fileinput.input(file_path, inplace=True) as file_object:
for line in file_object:
new_line = line.replace(search_text, new_text)
# This directs the output to the file, not the console
print(new_line, end="")


def mock_aws_lambda_exec_wrapper():
"""Mocks automatically instrumenting user Lambda function by pointing
`AWS_LAMBDA_EXEC_WRAPPER` to the `otel-instrument` script.
Expand All @@ -77,8 +90,26 @@ def mock_aws_lambda_exec_wrapper():
See more:
https://aws-otel.github.io/docs/getting-started/lambda/lambda-python
"""
# NOTE: AwsLambdaInstrumentor().instrument() is done at this point
exec(open(os.path.join(INSTRUMENTATION_SRC_DIR, "otel-instrument")).read())

# NOTE: Even though we run as a subprocess, the python packages are still
# patched with instrumentation. However, the environment values changed in
# the script have no effect here in the parent process.

subprocess.call(
[
os.path.join(INSTRUMENTATION_SRC_DIR, "otel-instrument"),
"python3",
"-c",
"pass",
]
)

# NOTE: This should have been done by `otel-instrument`... but because there
# is no way to run this bash script so that it can affect this python
# environment, we have to COPY and PASTE its duplicate here ourselves.

os.environ[ORIG_HANDLER] = os.environ[_HANDLER]
os.environ[_HANDLER] = "otel_wrapper.lambda_handler"


def mock_execute_lambda(event=None):
Expand All @@ -104,6 +135,11 @@ class TestAwsLambdaInstrumentor(TestBase):
def setUpClass(cls):
super().setUpClass()
sys.path.append(INSTRUMENTATION_SRC_DIR)
replace_in_file(
os.path.join(INSTRUMENTATION_SRC_DIR, "otel-instrument"),
'export LAMBDA_LAYER_PKGS_DIR="/opt/python"',
f'export LAMBDA_LAYER_PKGS_DIR="{TOX_PYTHON_DIRECTORY}"',
)

def setUp(self):
super().setUp()
Expand All @@ -123,6 +159,11 @@ def tearDown(self):
super().tearDown()
self.common_env_patch.stop()
AwsLambdaInstrumentor().uninstrument()
replace_in_file(
os.path.join(INSTRUMENTATION_SRC_DIR, "otel-instrument"),
f'export LAMBDA_LAYER_PKGS_DIR="{TOX_PYTHON_DIRECTORY}"',
'export LAMBDA_LAYER_PKGS_DIR="/opt/python"',
)

@classmethod
def tearDownClass(cls):
Expand Down
1 change: 0 additions & 1 deletion python/src/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ passenv = TOXENV

setenv =
OTEL_PYTHON_TRACER_PROVIDER=sdk_tracer_provider
OTEL_TRACES_EXPORTER="console_span"
; override CORE_REPO_SHA via env variable when testing other branches/commits than main
; i.e: CORE_REPO_SHA=dde62cebffe519c35875af6d06fae053b3be65ec tox -e <env to test>
CORE_REPO_SHA={env:CORE_REPO_SHA:main}
Expand Down

0 comments on commit f5b9cdf

Please sign in to comment.