Explicit component inheritance (#132)
diff --git a/README.md b/README.md
index 0c093e0..22a1431 100755
--- a/README.md
+++ b/README.md
@@ -79,8 +79,8 @@
span.component = Component.Flask
# the span automatically stops when exiting the `with` context
-with context.new_exit_span(op='https://github.com/apache', peer='localhost:8080') as span:
- span.component = Component.Flask
+with context.new_exit_span(op='https://github.com/apache', peer='localhost:8080', component=Component.Flask) as span:
+ span.tag(Tag(key='Singer', val='Nakajima'))
with context.new_local_span(op='https://github.com/apache') as span:
span.tag(Tag(key='Singer', val='Nakajima'))
diff --git a/skywalking/plugins/sw_aiohttp.py b/skywalking/plugins/sw_aiohttp.py
index ce3f0a8..c3b7c4d 100644
--- a/skywalking/plugins/sw_aiohttp.py
+++ b/skywalking/plugins/sw_aiohttp.py
@@ -33,9 +33,8 @@
peer = '%s:%d' % (url.host or '', url.port)
context = get_context()
- with context.new_exit_span(op=url.path or "/", peer=peer) as span:
+ with context.new_exit_span(op=url.path or "/", peer=peer, component=Component.AioHttp) as span:
span.layer = Layer.Http
- span.component = Component.AioHttp
span.tag(Tag(key=tags.HttpMethod, val=method.upper())) # pyre-ignore
span.tag(Tag(key=tags.HttpUrl, val=url)) # pyre-ignore
diff --git a/skywalking/plugins/sw_celery.py b/skywalking/plugins/sw_celery.py
index ae19ae8..173b2a5 100644
--- a/skywalking/plugins/sw_celery.py
+++ b/skywalking/plugins/sw_celery.py
@@ -42,9 +42,8 @@
else:
peer = '???'
- with get_context().new_exit_span(op=op, peer=peer) as span:
+ with get_context().new_exit_span(op=op, peer=peer, component=Component.Celery) as span:
span.layer = Layer.MQ
- span.component = Component.Celery
span.tag(Tag(key=tags.MqBroker, val=broker_url))
# span.tag(Tag(key=tags.MqTopic, val=exchange))
diff --git a/skywalking/plugins/sw_elasticsearch.py b/skywalking/plugins/sw_elasticsearch.py
index 0d64db4..a7d0327 100644
--- a/skywalking/plugins/sw_elasticsearch.py
+++ b/skywalking/plugins/sw_elasticsearch.py
@@ -28,9 +28,9 @@
def _sw_perform_request(this: Transport, method, url, headers=None, params=None, body=None):
context = get_context()
peer = ",".join([host["host"] + ":" + str(host["port"]) for host in this.hosts])
- with context.new_exit_span(op="Elasticsearch/" + method + url, peer=peer) as span:
+ with context.new_exit_span(op="Elasticsearch/" + method + url, peer=peer,
+ component=Component.Elasticsearch) as span:
span.layer = Layer.Database
- span.component = Component.Elasticsearch
res = _perform_request(this, method, url, headers=headers, params=params, body=body)
span.tag(Tag(key=tags.DbType, val="Elasticsearch"))
diff --git a/skywalking/plugins/sw_flask.py b/skywalking/plugins/sw_flask.py
index 037f6cf..62ffb68 100644
--- a/skywalking/plugins/sw_flask.py
+++ b/skywalking/plugins/sw_flask.py
@@ -41,7 +41,7 @@
for item in carrier:
if item.key.capitalize() in req.headers:
item.val = req.headers[item.key.capitalize()]
- with context.new_entry_span(op=req.path, carrier=carrier) as span:
+ with context.new_entry_span(op=req.path, carrier=carrier, inherit=Component.General) as span:
span.layer = Layer.Http
span.component = Component.Flask
span.peer = '%s:%s' % (req.environ["REMOTE_ADDR"], req.environ["REMOTE_PORT"])
diff --git a/skywalking/plugins/sw_kafka.py b/skywalking/plugins/sw_kafka.py
index 201f6a4..2ccd945 100644
--- a/skywalking/plugins/sw_kafka.py
+++ b/skywalking/plugins/sw_kafka.py
@@ -72,10 +72,10 @@
peer = ";".join(this.config["bootstrap_servers"])
context = get_context()
- with context.new_exit_span(op="Kafka/" + topic + "/Producer" or "/", peer=peer) as span:
+ with context.new_exit_span(op="Kafka/" + topic + "/Producer" or "/", peer=peer,
+ component=Component.KafkaProducer) as span:
carrier = span.inject()
span.layer = Layer.MQ
- span.component = Component.KafkaProducer
if headers is None:
headers = []
diff --git a/skywalking/plugins/sw_psycopg2.py b/skywalking/plugins/sw_psycopg2.py
index 01e65d4..27539f7 100644
--- a/skywalking/plugins/sw_psycopg2.py
+++ b/skywalking/plugins/sw_psycopg2.py
@@ -38,9 +38,9 @@
dsn = self.connection.get_dsn_parameters()
peer = dsn['host'] + ':' + dsn['port']
- with get_context().new_exit_span(op="PostgreSLQ/Psycopg/execute", peer=peer) as span:
+ with get_context().new_exit_span(op="PostgreSLQ/Psycopg/execute", peer=peer,
+ component=Component.Psycopg) as span:
span.layer = Layer.Database
- span.component = Component.Psycopg
span.tag(Tag(key=tags.DbType, val="PostgreSQL"))
span.tag(Tag(key=tags.DbInstance, val=dsn['dbname']))
@@ -60,9 +60,9 @@
dsn = self.connection.get_dsn_parameters()
peer = dsn['host'] + ':' + dsn['port']
- with get_context().new_exit_span(op="PostgreSLQ/Psycopg/executemany", peer=peer) as span:
+ with get_context().new_exit_span(op="PostgreSLQ/Psycopg/executemany", peer=peer,
+ component=Component.Psycopg) as span:
span.layer = Layer.Database
- span.component = Component.Psycopg
span.tag(Tag(key=tags.DbType, val="PostgreSQL"))
span.tag(Tag(key=tags.DbInstance, val=dsn['dbname']))
@@ -92,9 +92,9 @@
dsn = self.connection.get_dsn_parameters()
peer = dsn['host'] + ':' + dsn['port']
- with get_context().new_exit_span(op="PostgreSLQ/Psycopg/callproc", peer=peer) as span:
+ with get_context().new_exit_span(op="PostgreSLQ/Psycopg/callproc", peer=peer,
+ component=Component.Psycopg) as span:
span.layer = Layer.Database
- span.component = Component.Psycopg
args = '(' + ('' if not parameters else ','.join(parameters)) + ')'
span.tag(Tag(key=tags.DbType, val="PostgreSQL"))
diff --git a/skywalking/plugins/sw_pymongo.py b/skywalking/plugins/sw_pymongo.py
index 8aae500..0179d34 100644
--- a/skywalking/plugins/sw_pymongo.py
+++ b/skywalking/plugins/sw_pymongo.py
@@ -58,11 +58,10 @@
operation = list(spec.keys())[0]
sw_op = operation.capitalize() + "Operation"
- with context.new_exit_span(op="MongoDB/" + sw_op, peer=peer) as span:
+ with context.new_exit_span(op="MongoDB/" + sw_op, peer=peer, component=Component.MongoDB) as span:
result = _command(this, dbname, spec, *args, **kwargs)
span.layer = Layer.Database
- span.component = Component.MongoDB
span.tag(Tag(key=tags.DbType, val="MongoDB"))
span.tag(Tag(key=tags.DbInstance, val=dbname))
@@ -108,9 +107,8 @@
context = get_context()
sw_op = "MixedBulkWriteOperation"
- with context.new_exit_span(op="MongoDB/"+sw_op, peer=peer) as span:
+ with context.new_exit_span(op="MongoDB/"+sw_op, peer=peer, component=Component.MongoDB) as span:
span.layer = Layer.Database
- span.component = Component.MongoDB
bulk_result = _execute(this, *args, **kwargs)
@@ -143,9 +141,8 @@
context = get_context()
op = "FindOperation"
- with context.new_exit_span(op="MongoDB/"+op, peer=peer) as span:
+ with context.new_exit_span(op="MongoDB/"+op, peer=peer, component=Component.MongoDB) as span:
span.layer = Layer.Database
- span.component = Component.MongoDB
# __send_message return nothing
__send_message(this, operation)
diff --git a/skywalking/plugins/sw_pymysql.py b/skywalking/plugins/sw_pymysql.py
index 715f918..4c9edd5 100644
--- a/skywalking/plugins/sw_pymysql.py
+++ b/skywalking/plugins/sw_pymysql.py
@@ -30,9 +30,8 @@
peer = "%s:%s" % (this.connection.host, this.connection.port)
context = get_context()
- with context.new_exit_span(op="Mysql/PyMsql/execute", peer=peer) as span:
+ with context.new_exit_span(op="Mysql/PyMsql/execute", peer=peer, component=Component.PyMysql) as span:
span.layer = Layer.Database
- span.component = Component.PyMysql
res = _execute(this, query, args)
span.tag(Tag(key=tags.DbType, val="mysql"))
diff --git a/skywalking/plugins/sw_rabbitmq.py b/skywalking/plugins/sw_rabbitmq.py
index e595d74..5e2468a 100644
--- a/skywalking/plugins/sw_rabbitmq.py
+++ b/skywalking/plugins/sw_rabbitmq.py
@@ -41,10 +41,9 @@
context = get_context()
import pika
with context.new_exit_span(op="RabbitMQ/Topic/" + exchange + "/Queue/" + routing_key + "/Producer" or "/",
- peer=peer) as span:
+ peer=peer, component=Component.RabbitmqProducer) as span:
carrier = span.inject()
span.layer = Layer.MQ
- span.component = Component.RabbitmqProducer
properties = pika.BasicProperties() if properties is None else properties
if properties.headers is None:
diff --git a/skywalking/plugins/sw_redis.py b/skywalking/plugins/sw_redis.py
index 55113bf..b931e49 100644
--- a/skywalking/plugins/sw_redis.py
+++ b/skywalking/plugins/sw_redis.py
@@ -30,9 +30,8 @@
peer = "%s:%s" % (this.host, this.port)
op = args[0]
context = get_context()
- with context.new_exit_span(op="Redis/"+op or "/", peer=peer) as span:
+ with context.new_exit_span(op="Redis/"+op or "/", peer=peer, component=Component.Redis) as span:
span.layer = Layer.Cache
- span.component = Component.Redis
res = _send_command(this, *args, **kwargs)
span.tag(Tag(key=tags.DbType, val="Redis"))
diff --git a/skywalking/plugins/sw_requests.py b/skywalking/plugins/sw_requests.py
index 69397b5..31aae21 100644
--- a/skywalking/plugins/sw_requests.py
+++ b/skywalking/plugins/sw_requests.py
@@ -43,10 +43,10 @@
hooks, stream, verify, cert, json)
context = get_context()
- with context.new_exit_span(op=url_param.path or "/", peer=url_param.netloc) as span:
+ with context.new_exit_span(op=url_param.path or "/", peer=url_param.netloc,
+ component=Component.Requests) as span:
carrier = span.inject()
span.layer = Layer.Http
- span.component = Component.Requests
if headers is None:
headers = {}
diff --git a/skywalking/plugins/sw_urllib3.py b/skywalking/plugins/sw_urllib3.py
index 9f3f1cc..0d25c39 100644
--- a/skywalking/plugins/sw_urllib3.py
+++ b/skywalking/plugins/sw_urllib3.py
@@ -31,10 +31,10 @@
from urllib.parse import urlparse
url_param = urlparse(url)
context = get_context()
- with context.new_exit_span(op=url_param.path or "/", peer=url_param.netloc) as span:
+ with context.new_exit_span(op=url_param.path or "/", peer=url_param.netloc,
+ component=Component.Urllib3) as span:
carrier = span.inject()
span.layer = Layer.Http
- span.component = Component.Urllib3
if headers is None:
headers = {}
diff --git a/skywalking/plugins/sw_urllib_request.py b/skywalking/plugins/sw_urllib_request.py
index 66d138e..6b0a64e 100644
--- a/skywalking/plugins/sw_urllib_request.py
+++ b/skywalking/plugins/sw_urllib_request.py
@@ -36,10 +36,9 @@
context = get_context()
url = fullurl.selector.split("?")[0] if fullurl.selector else '/'
- with context.new_exit_span(op=url, peer=fullurl.host) as span:
+ with context.new_exit_span(op=url, peer=fullurl.host, component=Component.General) as span:
carrier = span.inject()
span.layer = Layer.Http
- span.component = Component.General
code = None
[fullurl.add_header(item.key, item.val) for item in carrier]
diff --git a/skywalking/trace/context.py b/skywalking/trace/context.py
index 431ff28..07b7734 100644
--- a/skywalking/trace/context.py
+++ b/skywalking/trace/context.py
@@ -15,7 +15,7 @@
# limitations under the License.
#
-from skywalking import agent, config
+from skywalking import Component, agent, config
from skywalking.trace import ID
from skywalking.trace.carrier import Carrier
from skywalking.trace.segment import Segment, SegmentRef
@@ -91,7 +91,7 @@
kind=Kind.Local,
)
- def new_entry_span(self, op: str, carrier: 'Carrier' = None) -> Span:
+ def new_entry_span(self, op: str, carrier: 'Carrier' = None, inherit: Component = None) -> Span:
span = self.ignore_check(op, Kind.Entry)
if span is not None:
return span
@@ -99,19 +99,23 @@
spans = _spans_dup()
parent = spans[-1] if spans else None # type: Span
- span = parent if parent is not None and parent.kind.is_entry else EntrySpan(
- context=self,
- sid=self._sid.next(),
- pid=parent.sid if parent else -1,
- )
- span.op = op
+ if parent is not None and parent.kind.is_entry and inherit == parent.component:
+ span = parent
+ span.op = op
+ else:
+ span = EntrySpan(
+ context=self,
+ sid=self._sid.next(),
+ pid=parent.sid if parent else -1,
+ op=op,
+ )
- if carrier is not None and carrier.is_valid:
- span.extract(carrier=carrier)
+ if carrier is not None and carrier.is_valid: # TODO: should this be done irrespective of inheritance?
+ span.extract(carrier=carrier)
return span
- def new_exit_span(self, op: str, peer: str) -> Span:
+ def new_exit_span(self, op: str, peer: str, component: Component = None, inherit: Component = None) -> Span:
span = self.ignore_check(op, Kind.Exit)
if span is not None:
return span
@@ -119,13 +123,22 @@
spans = _spans_dup()
parent = spans[-1] if spans else None # type: Span
- span = ExitSpan(
- context=self,
- sid=self._sid.next(),
- pid=parent.sid if parent else -1,
- op=op,
- peer=peer,
- )
+ if parent is not None and parent.kind.is_exit and component == parent.inherit:
+ span = parent
+ span.op = op
+ span.component = component
+ else:
+ span = ExitSpan(
+ context=self,
+ sid=self._sid.next(),
+ pid=parent.sid if parent else -1,
+ op=op,
+ peer=peer,
+ component=component,
+ )
+
+ if inherit:
+ span.inherit = inherit
return span
diff --git a/skywalking/trace/span.py b/skywalking/trace/span.py
index 2a473ac..80f000a 100644
--- a/skywalking/trace/span.py
+++ b/skywalking/trace/span.py
@@ -55,6 +55,7 @@
self.kind = kind # type: Kind
self.component = component or Component.Unknown # type: Component
self.layer = layer or Layer.Unknown # type: Layer
+ self.inherit = Component.Unknown # type: Component
self.tags = [] # type: List[Tag]
self.logs = [] # type: List[Log]