def tracer(): exporter = ConsoleSpanExporter() span_processor = SimpleExportSpanProcessor(exporter) trace.set_preferred_tracer_source_implementation(lambda T: TracerSource()) span_processor = SimpleExportSpanProcessor(exporter) trace.tracer_source().add_span_processor(span_processor) return trace.get_tracer(__name__)
def main(): model_name = "my-model" model_version = "v1" client = sczpy.SCZClient(server_url) trace.set_tracer_provider(TracerProvider()) jaeger_exporter = jaeger.JaegerSpanExporter( service_name="my-device", agent_host_name="localhost", agent_port=6831, ) trace.get_tracer_provider().add_span_processor( BatchExportSpanProcessor(jaeger_exporter)) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(sczpy.SCZSpanExporter(client))) tracer = trace.get_tracer(__name__) while True: with tracer.start_as_current_span("inference") as inference: inference.set_attribute('device', 'my-device') inference.add_event( 'inference', { "confidence": random.randint(80, 101), "model_name": model_name, "model_version": model_version, "file_ref": "dummy_data.txt" }) time.sleep(3)
def setup(): reload_module(opentelemetry_tracing) tracer_provider = TracerProvider() memory_exporter = InMemorySpanExporter() span_processor = SimpleExportSpanProcessor(memory_exporter) tracer_provider.add_span_processor(span_processor) trace.set_tracer_provider(tracer_provider) yield memory_exporter
def initialize_tracer(project_id): trace.set_tracer_provider(TracerProvider()) cloud_trace_exporter = CloudTraceSpanExporter(project_id) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(cloud_trace_exporter)) opentelemetry_tracer = trace.get_tracer(__name__) return opentelemetry_tracer
def init(tracefile: Optional[IO[str]] = None) -> None: tracer_provider = TracerProvider() if tracefile is not None: tracer_provider.add_span_processor( SimpleExportSpanProcessor( ConsoleSpanExporter(out=tracefile, formatter=single_line_json) ) ) trace.set_tracer_provider(tracer_provider)
def __init__(self): tracer_provider = trace.TracerProvider() oteltracer = tracer_provider.get_tracer(__name__) super(MockTracer, self).__init__(oteltracer) exporter = InMemorySpanExporter() span_processor = SimpleExportSpanProcessor(exporter) tracer_provider.add_span_processor(span_processor) self.exporter = exporter
def add_span_exporter(self, span_exporter: SpanExporter): """ Adds a span exporter that will be called to export completed spans. :param span_exporter: the span exporter :return: None """ logging.info(f"Added trace exporter: {span_exporter}") self.span_processor.add_span_processor( SimpleExportSpanProcessor(span_exporter))
def setUp(self): tracer_provider = TracerProvider() self.exporter = OTLPSpanExporter(insecure=True) tracer_provider.add_span_processor( SimpleExportSpanProcessor(self.exporter) ) self.tracer = tracer_provider.get_tracer(__name__) self.server = server(ThreadPoolExecutor(max_workers=10)) self.server.add_insecure_port("[::]:55680") self.server.start() event_mock = Mock( **{ "timestamp": 1591240820506462784, "attributes": OrderedDict([("a", 1), ("b", False)]), } ) type(event_mock).name = PropertyMock(return_value="a") self.span = _Span( "a", context=Mock( **{ "trace_state": OrderedDict([("a", "b"), ("c", "d")]), "span_id": 10217189687419569865, "trace_id": 67545097771067222548457157018666467027, } ), resource=SDKResource(OrderedDict([("a", 1), ("b", False)])), parent=Mock(**{"span_id": 12345}), attributes=OrderedDict([("a", 1), ("b", True)]), events=[event_mock], links=[ Mock( **{ "context.trace_id": 1, "context.span_id": 2, "attributes": OrderedDict([("a", 1), ("b", False)]), "kind": OTLPSpan.SpanKind.SPAN_KIND_INTERNAL, # pylint: disable=no-member } ) ], instrumentation_info=InstrumentationInfo( name="name", version="version" ), ) self.span.start() self.span.end() Configuration._reset() # pylint: disable=protected-access
def configure_tracing(configuration: dict): # OTLP Exporter configuration if configuration['exporter'] == 'otlp': service_name = {'service.name': configuration['service_name']} resource = Resource(service_name) trace.set_tracer_provider(TracerProvider(resource=resource)) exporter = OTLPSpanExporter( endpoint=configuration['exporter_endpoint'], insecure=configuration['exporter_insecure']) trace.get_tracer(__name__) span_processor = BatchExportSpanProcessor(exporter) trace.get_tracer_provider().add_span_processor(span_processor) # Jaeger HTTP Exporter configuration elif configuration['exporter'] == 'jaeger_http': exporter = JaegerSpanExporter( service_name=configuration['service_name'], collector_endpoint=configuration['exporter_endpoint'], ) trace.set_tracer_provider(TracerProvider()) trace.get_tracer(__name__) span_processor = BatchExportSpanProcessor(exporter) trace.get_tracer_provider().add_span_processor(span_processor) # Jaeger Thrifth Compact Exporter configuration elif configuration['exporter'] == 'jaeger_thrift': exporter = JaegerSpanExporter( service_name=configuration['service_name'], agent_host_name=configuration['exporter_host'], agent_port=configuration['exporter_port'], ) trace.set_tracer_provider(TracerProvider()) trace.get_tracer(__name__) span_processor = BatchExportSpanProcessor(exporter) trace.get_tracer_provider().add_span_processor(span_processor) # Zipkin Exporter configuration elif configuration['exporter'] == 'zipkin': exporter = ZipkinSpanExporter( service_name=configuration['service_name'], url=configuration['exporter_endpoint']) trace.set_tracer_provider(TracerProvider()) trace.get_tracer(__name__) span_processor = BatchExportSpanProcessor(exporter) trace.get_tracer_provider().add_span_processor(span_processor) # Console Exporter configuration elif configuration['exporter'] == 'console': trace.set_tracer_provider(TracerProvider()) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(ConsoleSpanExporter())) else: raise ValueError( 'Only Otlp, Jaeger Thrift/HTTP and Zipkin exporters are supported. ' 'Please check your configuration.')
def _grpc(): """Start discount gRPC server.""" logging.basicConfig(level=logging.INFO) engine = create_engine(settings.DATABASE_URL) Session = sessionmaker(bind=engine) connection = engine.connect() session = Session(bind=connection) exporter = ConsoleSpanExporter() if settings.TRACER_ENDPOINT_HOST and settings.TRACER_ENDPOINT_PORT: exporter = JaegerSpanExporter( service_name="promotion-grpc", agent_host_name=settings.TRACER_ENDPOINT_HOST, agent_port=settings.TRACER_ENDPOINT_PORT, ) trace.set_preferred_tracer_source_implementation(lambda T: TracerSource()) tracer = trace.get_tracer(__name__) ## span_processor = BatchExportSpanProcessor(exporter) span_processor = SimpleExportSpanProcessor(exporter) trace.tracer_source().add_span_processor(span_processor) tracer = trace.get_tracer(__name__) user_store = UserDataStore(session, tracer) user_case = UserUseCase(user_store, tracer) order_store = OrderDataStore(session, tracer) order_case = OrderUseCase(order_store, tracer) balance_client = BalanceClient(settings.BALANCE_TOKEN) balance_case = BalanceUseCase(order_case, balance_client, tracer) holiday_store = HolidayDataStore(settings.BLACK_FRIDAY_DATE, tracer) holiday_case = HolidayUseCase(holiday_store, tracer) authentication_case = AuthenticationUseCase(user_case, tracer) case = PromotionUseCase(discounts=[holiday_case, user_case], tracer=tracer) servicer = PromotionServicer(case, user_case, order_case, balance_case, authentication_case, tracer) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) service.add_PromotionAPIServicer_to_server(servicer, server) logger.info("Listenning on port 50051.") server.add_insecure_port("[::]:50051") server.start() server.wait_for_termination()
def setUpClass(cls): cls._tracer_source = TracerSource() cls._tracer = Tracer(cls._tracer_source, None) cls._span_exporter = InMemorySpanExporter() cls._span_processor = SimpleExportSpanProcessor(cls._span_exporter) cls._tracer_source.add_span_processor(cls._span_processor) trace_integration(cls._tracer) client = MongoClient(MONGODB_HOST, MONGODB_PORT, serverSelectionTimeoutMS=2000) db = client[MONGODB_DB_NAME] cls._collection = db[MONGODB_COLLECTION_NAME]
def setup_tracing() -> None: """Stand-in for a user-provided `setup_tracing` hook.""" os.makedirs("/tmp/spans", exist_ok=True) # Sets the tracer_provider. This is only allowed once per execution # context and will log a warning if attempted multiple times. trace.set_tracer_provider(TracerProvider()) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor( ConsoleSpanExporter( out=open(f"{spans_dir}{os.getpid()}.txt", "w"), formatter=lambda span: span.to_json(indent=None) + os.linesep, )))
def serve(): trace.set_tracer_provider(TracerProvider()) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(ConsoleSpanExporter())) propagators.set_global_textmap(B3Format()) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[server_interceptor()]) add_ImageServiceServicer_to_server(ImageServer(), server) server.add_insecure_port("[::]:50051") server.start() server.wait_for_termination()
def setUp(self): tracer_provider = TracerProvider() self.exporter = OTLPSpanExporter() tracer_provider.add_span_processor( SimpleExportSpanProcessor(self.exporter) ) self.tracer = tracer_provider.get_tracer(__name__) self.server = server(ThreadPoolExecutor(max_workers=10)) self.server.add_insecure_port("[::]:55678") self.server.start() event_mock = Mock( **{ "timestamp": 1591240820506462784, "attributes": OrderedDict([("a", 1), ("b", False)]), } ) type(event_mock).name = PropertyMock(return_value="a") self.span = Span( "a", context=Mock( **{ "trace_state": OrderedDict([("a", "b"), ("c", "d")]), "span_id": 10217189687419569865, "trace_id": 67545097771067222548457157018666467027, } ), resource=SDKResource(OrderedDict([("a", 1), ("b", False)])), parent=Mock(**{"span_id": 12345}), attributes=OrderedDict([("a", 1), ("b", True)]), events=[event_mock], links=[ Mock( **{ "context.trace_id": 1, "context.span_id": 2, "attributes": OrderedDict([("a", 1), ("b", False)]), "kind": SpanKind.INTERNAL, } ) ], ) self.span.start() self.span.end()
def create_grpc_server(is_prod: bool) -> grpc.Server: console_span_processor = SimpleExportSpanProcessor(ConsoleSpanExporter()) if is_prod: span_processor = MultiSpanProcessor() span_processor.add_span_processor(console_span_processor) span_processor.add_span_processor( BatchExportSpanProcessor(CloudTraceSpanExporter())) else: span_processor = console_span_processor # this should typecheck but the API interface doesn't have add_span_processor() trace.get_tracer_provider().add_span_processor( # type: ignore span_processor) server = grpc.server(ThreadPoolExecutor(max_workers=10)) server = intercept_server(server, server_interceptor()) return server
def setUpClass(cls): cls._connection = None cls._cursor = None cls._tracer_provider = TracerProvider() cls._tracer = Tracer(cls._tracer_provider, None) cls._span_exporter = InMemorySpanExporter() cls._span_processor = SimpleExportSpanProcessor(cls._span_exporter) cls._tracer_provider.add_span_processor(cls._span_processor) trace_integration(cls._tracer) cls._connection = mysql.connector.connect( user=MYSQL_USER, password=MYSQL_PASSWORD, host=MYSQL_HOST, port=MYSQL_PORT, database=MYSQL_DB_NAME, ) cls._cursor = cls._connection.cursor()
def setUpClass(cls): cls._connection = None cls._cursor = None cls._tracer_provider = TracerProvider() cls._tracer = Tracer(cls._tracer_provider, None) cls._span_exporter = InMemorySpanExporter() cls._span_processor = SimpleExportSpanProcessor(cls._span_exporter) cls._tracer_provider.add_span_processor(cls._span_processor) trace_integration(cls._tracer) cls._connection = psycopg2.connect( dbname=POSTGRES_DB_NAME, user=POSTGRES_USER, password=POSTGRES_PASSWORD, host=POSTGRES_HOST, port=POSTGRES_PORT, ) cls._connection.set_session(autocommit=True) cls._cursor = cls._connection.cursor()
def serve(): trace.set_tracer_provider(TracerProvider()) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(ConsoleSpanExporter()) ) propagators.set_global_textmap(B3Format()) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[server_interceptor()]) add_ProductInfoServicer_to_server(ProductInfoServer(), server) server.add_insecure_port("[::]:50050") server.start() proxy = MyProxy(ProductInfoServer) try: proxy.start() server.wait_for_termination() except KeyboardInterrupt: print("terminating") proxy.stop() print("Goodbye")
def set_up(service_name: str): """Instantiate and configure the span exporter. The exporter is select and configured through environment variables. Parameters ---------- service_name : str The name under which the data is exported. """ if tracing_settings.TRACING_EXPORTER.lower() == "jaeger": from opentelemetry.sdk.trace.export import BatchExportSpanProcessor jaeger_exporter = jaeger.JaegerSpanExporter( service_name=service_name, agent_host_name=tracing_settings.JAEGER_AGENT_HOST_NAME, agent_port=tracing_settings.JAEGER_AGENT_PORT, ) trace.get_tracer_provider().add_span_processor( BatchExportSpanProcessor(jaeger_exporter)) elif tracing_settings.TRACING_EXPORTER.lower() == "console": from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor, ConsoleSpanExporter trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(ConsoleSpanExporter())) elif tracing_settings.TRACING_EXPORTER == "gcp": from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter from opentelemetry.tools.cloud_trace_propagator import CloudTraceFormatPropagator from opentelemetry.sdk.trace.export import BatchExportSpanProcessor from opentelemetry.propagators import set_global_textmap cloud_trace_exporter = CloudTraceSpanExporter() trace.get_tracer_provider().add_span_processor( BatchExportSpanProcessor(cloud_trace_exporter)) set_global_textmap(CloudTraceFormatPropagator())
# 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. from opentelemetry import trace from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter from opentelemetry.sdk.resources import get_aggregated_resources from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor from opentelemetry.tools.resource_detector import GoogleCloudResourceDetector # MUST be run on a Google tool! # Detect resources from the environment resources = get_aggregated_resources( [GoogleCloudResourceDetector(raise_on_error=True)] ) # Pass the detected resources to the provider, which will in turn pass it to all # created spans trace.set_tracer_provider(TracerProvider(resource=resources)) # Cloud Trace exporter will automatically format these resources and export cloud_trace_exporter = CloudTraceSpanExporter() trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(cloud_trace_exporter) ) tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("foo"): print("Hello world!")
from flask import Flask, request from opentelemetry import propagators, trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, SimpleExportSpanProcessor, ) app = Flask(__name__) trace.set_tracer_provider(TracerProvider()) tracer = trace.get_tracer_provider().get_tracer(__name__) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(ConsoleSpanExporter())) @app.route("/server_request") def server_request(): with tracer.start_as_current_span( "server_request", parent=propagators.extract(lambda dict_, key: dict_.get(key, []), request.headers)["current-span"], ): print(request.args.get("param")) return "served" if __name__ == "__main__": app.run(port=8082)
# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # pylint: disable=import-error # pylint: disable=no-member # pylint: disable=no-name-in-module import os import requests from opentelemetry import trace from opentelemetry.instrumentation.requests import RequestsInstrumentor from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor from microsoft.opentelemetry.exporter.azuremonitor import AzureMonitorTraceExporter trace.set_tracer_provider(TracerProvider()) RequestsInstrumentor().instrument() span_processor = SimpleExportSpanProcessor( AzureMonitorTraceExporter( connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"])) trace.get_tracer_provider().add_span_processor(span_processor) tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("parent"): response = requests.get("https://azure.microsoft.com/", timeout=5) input("Press any key to exit...")
from opentelemetry.sdk.resources import Resource class MockLambdaContext: pass lambdaContext = MockLambdaContext() lambdaContext.invoked_function_arn = "arn://mock-lambda-function-arn" lambdaContext.aws_request_id = "mock_aws_request_id" # TODO: does not work, need upstream fix resource = Resource.create().merge(AwsLambdaResourceDetector().detect()) trace.set_tracer_provider(TracerProvider(resource=resource, )) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(ConsoleSpanExporter()), ) in_memory_exporter = InMemorySpanExporter() trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(in_memory_exporter)) def test_lambda_instrument(): in_memory_exporter.clear() lambda_handler("mock", lambdaContext) spans = in_memory_exporter.get_finished_spans() assert len(spans) == 1 span = spans[0] assert span.name == "mock_lambda.handler"
from opentelemetry.ext.http_requests import enable from opentelemetry.ext.wsgi import OpenTelemetryMiddleware from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor from kitchen_service import KitchenService from kitchen_consumer import KitchenConsumer from donut import Donut from status import NEW_ORDER trace.set_preferred_tracer_implementation(lambda T: Tracer()) propagators.set_global_httptextformat(B3Format()) tracer = trace.tracer() enable(tracer) tracer.add_span_processor(SimpleExportSpanProcessor(ConsoleSpanExporter())) app = Flask(__name__) app.static_folder = 'static' app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app) kitchen_service = KitchenService() kitchen_consumer = KitchenConsumer() @app.route('/') def home(): return render_template('index.html')
import opentelemetry.ext.requests from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor from opentelemetry.ext.flask import FlaskInstrumentor from opentelemetry.ext import jaeger trace.set_tracer_provider(TracerProvider()) jaeger_exporter = jaeger.JaegerSpanExporter(service_name="my-flask-service", agent_host_name="localhost", agent_port=6831) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(jaeger_exporter)) app = flask.Flask(__name__) FlaskInstrumentor().instrument_app(app) # opentelemetry.ext.http_requests.RequestsInstrumentor().instrument() opentelemetry.ext.requests.RequestsInstrumentor().instrument() @app.route("/") def hello(): tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("example-request"): requests.get("http://www.example.com") return "hello" app.run(debug=True, port=5100)
from opentelemetry.ext.wsgi import collect_request_attributes from opentelemetry.ext.otlp.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor logging.basicConfig(level=logging.DEBUG) app = Flask(__name__) trace.set_tracer_provider( TracerProvider(resource=Resource({"service.name": "backend"}))) tracer = trace.get_tracer_provider().get_tracer(__name__) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor( OTLPSpanExporter(endpoint="opentelemetry-collector:55680"))) @app.route("/backend") def server_request(): with tracer.start_as_current_span( "GET /backend", parent=propagators.extract( lambda request, key: request.headers.get_all(key), request)["current-span"], kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(request.environ), ) as foo: return "served"
CloudTraceFormatPropagator, ) from flask import Flask # Instrumenting requests opentelemetry.ext.requests.RequestsInstrumentor().instrument() # Instrumenting flask app = Flask(__name__) FlaskInstrumentor().instrument_app(app) # Tracer boilerplate trace.set_tracer_provider(TracerProvider()) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(CloudTraceSpanExporter()) ) # Using the X-Cloud-Trace-Context header set_global_textmap(CloudTraceFormatPropagator()) @app.route("/") def hello_world(): tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("server_span"): return "Hello World!" if __name__ == "__main__": port = 5000
{ "service.name": "order", "service.instance.id": str(id(app)), "telemetry.sdk.name": "opentelemetry", "telemetry.sdk.language": "python", "telemetry.sdk.version": pkg_resources.get_distribution("opentelemetry-sdk").version, "host.hostname": socket.gethostname(), } ) ) ) tracerProvider = trace.get_tracer_provider() tracer = tracerProvider.get_tracer(__name__) tracerProvider.add_span_processor( SimpleExportSpanProcessor(ConsoleSpanExporter()) ) otlp_exporter = OTLPSpanExporter(endpoint="{}:55680".format(OTLP)) tracerProvider.add_span_processor( SimpleExportSpanProcessor(otlp_exporter) ) FlaskInstrumentor().instrument_app(app) RequestsInstrumentor().instrument(tracer_provider=tracerProvider) @app.errorhandler(Error) def handle_invalid_usage(error): response = jsonify(error.to_dict()) response.status_code = error.status_code return response
def create_app(): """Flask application factory to create instances of the Userservice Flask App """ app = Flask(__name__) # Set up tracing and export spans to Cloud Trace trace.set_tracer_provider(TracerProvider()) cloud_trace_exporter = CloudTraceSpanExporter() trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(cloud_trace_exporter)) set_global_httptextformat(CloudTraceFormatPropagator()) # Add Flask auto-instrumentation for tracing FlaskInstrumentor().instrument_app(app) # Disabling unused-variable for lines with route decorated functions # as pylint thinks they are unused # pylint: disable=unused-variable @app.route('/version', methods=['GET']) def version(): """ Service version endpoint """ return app.config['VERSION'], 200 @app.route('/ready', methods=['GET']) def readiness(): """ Readiness probe """ return 'ok', 200 @app.route('/users', methods=['POST']) def create_user(): """Create a user record. Fails if that username already exists. Generates a unique accountid. request fields: - username - password - password-repeat - firstname - lastname - birthday - timezone - address - state - zip - ssn """ try: app.logger.debug('Sanitizing input.') req = {k: bleach.clean(v) for k, v in request.form.items()} __validate_new_user(req) # Check if user already exists if users_db.get_user(req['username']) is not None: raise NameError('user {} already exists'.format( req['username'])) # Create password hash with salt app.logger.debug("Creating password hash.") password = req['password'] salt = bcrypt.gensalt() passhash = bcrypt.hashpw(password.encode('utf-8'), salt) accountid = users_db.generate_accountid() # Create user data to be added to the database user_data = { 'accountid': accountid, 'username': req['username'], 'passhash': passhash, 'firstname': req['firstname'], 'lastname': req['lastname'], 'birthday': req['birthday'], 'timezone': req['timezone'], 'address': req['address'], 'state': req['state'], 'zip': req['zip'], 'ssn': req['ssn'], } # Add user_data to database app.logger.debug("Adding user to the database") users_db.add_user(user_data) app.logger.info("Successfully created user.") except UserWarning as warn: app.logger.error("Error creating new user: %s", str(warn)) return str(warn), 400 except NameError as err: app.logger.error("Error creating new user: %s", str(err)) return str(err), 409 except SQLAlchemyError as err: app.logger.error("Error creating new user: %s", str(err)) return 'failed to create user', 500 return jsonify({}), 201 def __validate_new_user(req): app.logger.debug('validating create user request: %s', str(req)) # Check if required fields are filled fields = ( 'username', 'password', 'password-repeat', 'firstname', 'lastname', 'birthday', 'timezone', 'address', 'state', 'zip', 'ssn', ) if any(f not in req for f in fields): raise UserWarning('missing required field(s)') if any(not bool(req[f] or req[f].strip()) for f in fields): raise UserWarning('missing value for input field(s)') # Verify username contains only 2-15 alphanumeric or underscore characters if not re.match(r"\A[a-zA-Z0-9_]{2,15}\Z", req['username']): raise UserWarning( 'username must contain 2-15 alphanumeric characters or underscores' ) # Check if passwords match if not req['password'] == req['password-repeat']: raise UserWarning('passwords do not match') @app.route('/login', methods=['GET']) def login(): """Login a user and return a JWT token Fails if username doesn't exist or password doesn't match hash token expiry time determined by environment variable request fields: - username - password """ app.logger.debug('Sanitizing login input.') username = bleach.clean(request.args.get('username')) password = bleach.clean(request.args.get('password')) # Get user data try: app.logger.debug('Getting the user data.') user = users_db.get_user(username) if user is None: raise LookupError('user {} does not exist'.format(username)) # Validate the password app.logger.debug('Validating the password.') if not bcrypt.checkpw(password.encode('utf-8'), user['passhash']): raise PermissionError('invalid login') full_name = '{} {}'.format(user['firstname'], user['lastname']) exp_time = datetime.utcnow() + timedelta( seconds=app.config['EXPIRY_SECONDS']) payload = { 'user': username, 'acct': user['accountid'], 'name': full_name, 'iat': datetime.utcnow(), 'exp': exp_time, } app.logger.debug('Creating jwt token.') token = jwt.encode(payload, app.config['PRIVATE_KEY'], algorithm='RS256') app.logger.info('Login Successful.') return jsonify({'token': token.decode("utf-8")}), 200 except LookupError as err: app.logger.error('Error logging in: %s', str(err)) return str(err), 404 except PermissionError as err: app.logger.error('Error logging in: %s', str(err)) return str(err), 401 except SQLAlchemyError as err: app.logger.error('Error logging in: %s', str(err)) return 'failed to retrieve user information', 500 @atexit.register def _shutdown(): """Executed when web app is terminated.""" app.logger.info("Stopping userservice.") # Set up logger app.logger.handlers = logging.getLogger('gunicorn.error').handlers app.logger.setLevel(logging.getLogger('gunicorn.error').level) app.logger.info('Starting userservice.') app.config['VERSION'] = os.environ.get('VERSION') app.config['EXPIRY_SECONDS'] = int(os.environ.get('TOKEN_EXPIRY_SECONDS')) app.config['PRIVATE_KEY'] = open(os.environ.get('PRIV_KEY_PATH'), 'r').read() app.config['PUBLIC_KEY'] = open(os.environ.get('PUB_KEY_PATH'), 'r').read() # Configure database connection try: users_db = UserDb(os.environ.get("ACCOUNTS_DB_URI"), app.logger) except OperationalError: app.logger.critical("users_db database connection failed") sys.exit(1) return app
from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, SimpleExportSpanProcessor, ) # The preferred tracer implementation must be set, as the opentelemetry-api # defines the interface with a no-op implementation. trace.set_preferred_tracer_source_implementation(lambda T: TracerSource()) # Integrations are the glue that binds the OpenTelemetry API and the # frameworks and libraries that are used together, automatically creating # Spans and propagating context as appropriate. http_requests.enable(trace.tracer_source()) # SpanExporter receives the spans and send them to the target location. span_processor = SimpleExportSpanProcessor(ConsoleSpanExporter()) trace.tracer_source().add_span_processor(span_processor) app = flask.Flask(__name__) app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app) @app.route("/verify-tracecontext", methods=["POST"]) def verify_tracecontext(): """Upon reception of some payload, sends a request back to the designated url. This route is designed to be testable with the w3c tracecontext server / client test. """ for action in flask.request.json: