Source code for osprofiler.drivers.mongodb

# Copyright 2016 Mirantis Inc.
# All Rights Reserved.
#    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
#    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.

from osprofiler.drivers import base
from osprofiler import exc

[docs]class MongoDB(base.Driver): def __init__(self, connection_str, db_name="osprofiler", project=None, service=None, host=None, **kwargs): """MongoDB driver for OSProfiler.""" super(MongoDB, self).__init__(connection_str, project=project, service=service, host=host, **kwargs) try: from pymongo import MongoClient except ImportError: raise exc.CommandError( "To use OSProfiler with MongoDB driver, " "please install `pymongo` library. " "To install with pip:\n `pip install pymongo`.") client = MongoClient(self.connection_str, connect=False) self.db = client[db_name]
[docs] @classmethod def get_name(cls): return "mongodb"
[docs] def notify(self, info): """Send notifications to MongoDB. :param info: Contains information about trace element. In payload dict there are always 3 ids: "base_id" - uuid that is common for all notifications related to one trace. Used to simplify retrieving of all trace elements from MongoDB. "parent_id" - uuid of parent element in trace "trace_id" - uuid of current element in trace With parent_id and trace_id it's quite simple to build tree of trace elements, which simplify analyze of trace. """ data = info.copy() data["project"] = self.project data["service"] = self.service self.db.profiler.insert_one(data) if (self.filter_error_trace and data.get("info", {}).get("etype") is not None): self.notify_error_trace(data)
[docs] def notify_error_trace(self, data): """Store base_id and timestamp of error trace to a separate db.""" self.db.profiler_error.update( {"base_id": data["base_id"]}, {"base_id": data["base_id"], "timestamp": data["timestamp"]}, upsert=True )
[docs] def list_traces(self, fields=None): """Query all traces from the storage. :param fields: Set of trace fields to return. Defaults to 'base_id' and 'timestamp' :returns: List of traces, where each trace is a dictionary containing at least `base_id` and `timestamp`. """ fields = set(fields or self.default_trace_fields) ids = self.db.profiler.find({}).distinct("base_id") out_format = {"base_id": 1, "timestamp": 1, "_id": 0} out_format.update({i: 1 for i in fields}) return [self.db.profiler.find( {"base_id": i}, out_format).sort("timestamp")[0] for i in ids]
[docs] def list_error_traces(self): """Returns all traces that have error/exception.""" out_format = {"base_id": 1, "timestamp": 1, "_id": 0} return self.db.profiler_error.find({}, out_format)
[docs] def get_report(self, base_id): """Retrieves and parses notification from MongoDB. :param base_id: Base id of trace elements. """ for n in self.db.profiler.find({"base_id": base_id}, {"_id": 0}): trace_id = n["trace_id"] parent_id = n["parent_id"] name = n["name"] project = n["project"] service = n["service"] host = n["info"]["host"] timestamp = n["timestamp"] self._append_results(trace_id, parent_id, name, project, service, host, timestamp, n) return self._parse_results()