Files
opentelemetry-python-contrib/scripts/generate_instrumentation_bootstrap.py
wrisa 80d5ba1f40 Start supporting langchain instrumentation (#3600)
* Added base files for the project

* Added fix for generate and pre-commit

* Added package.py

* tox generate changes to auto-generated files

* tox ruff reformatted file

* removed python 3.8 from classifiers

* addressed comments

* addressed aabmass's comments
2025-07-25 14:41:27 -04:00

139 lines
4.6 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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 ast
import logging
import os
import subprocess
import sys
import astor
from otel_packaging import (
get_instrumentation_packages,
root_path,
scripts_path,
)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("instrumentation_list_generator")
_template = """
{header}
# DO NOT EDIT. THIS FILE WAS AUTOGENERATED FROM INSTRUMENTATION PACKAGES.
# RUN `python scripts/generate_instrumentation_bootstrap.py` TO REGENERATE.
{source}
"""
_source_tmpl = """
libraries = {}
default_instrumentations = []
"""
gen_path = os.path.join(
root_path,
"opentelemetry-instrumentation",
"src",
"opentelemetry",
"instrumentation",
"bootstrap_gen.py",
)
packages_to_exclude = [
# AWS Lambda instrumentation is excluded from the default list because it often
# requires specific configurations and dependencies that may not be set up
# in all environments. Instead, users who need AWS Lambda support can opt-in
# by manually adding it to their environment.
# See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/2787
"opentelemetry-instrumentation-aws-lambda",
# Google GenAI instrumentation is currently excluded because it is still in early
# development. This filter will get removed once it is further along in its
# development lifecycle and ready to be included by default.
"opentelemetry-instrumentation-google-genai",
# Langchain instrumentation is currently excluded because it is still in early
# development. This filter will get removed once it is further along in its
# development lifecycle and ready to be included by default.
"opentelemetry-instrumentation-langchain",
]
# Static version specifiers for instrumentations that are released independently
independent_packages = {
"opentelemetry-instrumentation-openai-v2": "",
"opentelemetry-instrumentation-vertexai": ">=2.0b0",
"opentelemetry-instrumentation-google-genai": "",
}
def main():
# pylint: disable=no-member
default_instrumentations = ast.List(elts=[])
libraries = ast.List(elts=[])
for pkg in get_instrumentation_packages(
independent_packages=independent_packages
):
pkg_name = pkg.get("name")
if pkg_name in packages_to_exclude:
continue
if not pkg["instruments"] and not pkg["instruments-any"]:
default_instrumentations.elts.append(ast.Str(pkg["requirement"]))
for target_pkg in pkg["instruments"]:
libraries.elts.append(
ast.Dict(
keys=[ast.Str("library"), ast.Str("instrumentation")],
values=[ast.Str(target_pkg), ast.Str(pkg["requirement"])],
)
)
# instruments-any is an optional field that can be used instead of or in addition to _instruments. While _instruments is a list of dependencies, all of which are expected by the instrumentation, instruments-any is a list any of which but not all are expected.
for target_pkg in pkg["instruments-any"]:
libraries.elts.append(
ast.Dict(
keys=[ast.Str("library"), ast.Str("instrumentation")],
values=[ast.Str(target_pkg), ast.Str(pkg["requirement"])],
)
)
tree = ast.parse(_source_tmpl)
tree.body[0].value = libraries
tree.body[1].value = default_instrumentations
source = astor.to_source(tree)
with open(
os.path.join(scripts_path, "license_header.txt"), encoding="utf-8"
) as header_file:
header = header_file.read()
source = _template.format(header=header, source=source)
with open(gen_path, "w", encoding="utf-8") as gen_file:
gen_file.write(source)
subprocess.run(
[
sys.executable,
"scripts/eachdist.py",
"format",
"--path",
"opentelemetry-instrumentation/src",
],
check=True,
)
logger.info("generated %s", gen_path)
if __name__ == "__main__":
main()