Skip to content
This repository was archived by the owner on Jun 13, 2023. It is now read-only.

Commit d2eca4a

Browse files
author
ranrib
committed
Initial commit.
0 parents  commit d2eca4a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+5153
-0
lines changed

Diff for: .gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.idea
2+
*.pyc
3+
.pypirc
4+
.coverage
5+
.cache
6+
dist
7+
.eggs
8+
.pytest_cache
9+
build
10+
epsagon.egg-info

Diff for: .pylintrc

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Based on:
2+
# https://github.com/kpreid/shinysdr/blob/master/pylintrc
3+
4+
[MASTER]
5+
# XXX should be changed to your project folder
6+
# see http://stackoverflow.com/a/37238692/3828891 for explanation
7+
init-hook='base_dir="epsagon"; import sys,os,re; _re=re.search(r".+\/" + base_dir, os.getcwd()); project_dir = _re.group() if _re else os.path.join(os.getcwd(), base_dir); sys.path.append(project_dir)'
8+
9+
[MESSAGES CONTROL]
10+
# Find available symbolic names in:
11+
# https://docs.pylint.org/features.html
12+
disable=duplicate-code,too-few-public-methods,too-many-arguments,fixme,too-many-instance-attributes,bad-continuation,useless-object-inheritance
13+
14+
[FORMAT]
15+
# Maximum number of characters on a single line.
16+
max-line-length=80
17+
18+
# Maximum number of lines in a module
19+
max-module-lines=500

Diff for: .travis.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
language: python
2+
notifications:
3+
slack: epsagon:Q0XcrHSJRI5YkYftfUzl83Lx
4+
python:
5+
- "2.7"
6+
- "3.6"
7+
install:
8+
- pip install -r requirements-dev.txt
9+
- pip install pylint
10+
before_script:
11+
- "pylint --msg-template='{path}:{line}: [{msg_id}({symbol}) {obj}] {msg}' epsagon/"
12+
script:
13+
- pytest

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Epsagon
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: MANIFEST.in

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include *.py *.md *.txt LICENSE
2+
recursive-include epsagon

Diff for: README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Epsagon Instrumentation for Python
2+
[![Build Status](https://travis-ci.com/epsagon/epsagon-python.svg?token=wsveVqcNtBtmq6jpZfSf&branch=master)](https://travis-ci.com/epsagon/epsagon-python)
3+
[![Pyversions](https://img.shields.io/pypi/pyversions/epsagon.svg?style=flat)](https://pypi.org/project/epsagon/)
4+
[![PypiVersions](https://img.shields.io/pypi/v/epsagon.svg)](https://pypi.org/project/epsagon/)
5+
6+
This package provides an instrumentation to Python code running on functions for collection of distributed tracing and performance monitoring.
7+
8+
9+
## Installation
10+
11+
From your project directory:
12+
13+
```
14+
$ pip install epsagon -t .
15+
16+
# If running in virtualenv:
17+
$ pip install epsagon
18+
```
19+
20+
More details about lambda deployments are available in the [AWS documentation](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html).
21+
22+
## Basic Usage
23+
24+
Simply use our decorator to report metrics:
25+
26+
```python
27+
import epsagon
28+
epsagon.init(
29+
token='my-secret-token',
30+
app_name='my-app-name', # Optional, used in the dashboard
31+
metadata_only=False, # Optional, send more trace data
32+
)
33+
34+
@epsagon.lambda_wrapper
35+
def handler(event, context):
36+
pass
37+
```
38+
39+
## Copyright
40+
41+
Provided under the MIT license. See LICENSE for details.
42+
43+
Copyright 2018, Epsagon.

Diff for: epsagon/__init__.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
Epsagon's init.
3+
"""
4+
5+
from __future__ import absolute_import
6+
import os
7+
from .utils import init
8+
from .patcher import patch_all
9+
from .constants import __version__
10+
from .trace import tracer
11+
12+
13+
def dummy_wrapper(func):
14+
"""
15+
A dummy wrapper for when Epsagon is disabled
16+
:param func: The function to wrap
17+
:return: The same function, unchanged
18+
"""
19+
return func
20+
21+
22+
if os.environ.get('DISABLE_EPSAGON') == 'TRUE':
23+
os.environ['DISABLE_EPSAGON_PATCH'] = 'TRUE'
24+
lambda_wrapper = dummy_wrapper # pylint: disable=C0103
25+
step_lambda_wrapper = dummy_wrapper # pylint: disable=C0103
26+
azure_wrapper = dummy_wrapper # pylint: disable=C0103
27+
python_wrapper = dummy_wrapper # pylint: disable=C0103
28+
EpsagonFlask = dummy_wrapper # pylint: disable=C0103
29+
else:
30+
# Environments.
31+
from .wrappers import (
32+
lambda_wrapper,
33+
step_lambda_wrapper,
34+
azure_wrapper,
35+
python_wrapper
36+
)
37+
38+
# Frameworks.
39+
try:
40+
from .wrappers.flask import FlaskWrapper as flask_wrapper
41+
except ImportError:
42+
flask_wrapper = dummy_wrapper
43+
44+
45+
# pylint: disable=C0103
46+
log = tracer.add_log
47+
# pylint: disable=C0103
48+
error = tracer.add_error
49+
50+
__all__ = ['lambda_wrapper', 'azure_wrapper', 'python_wrapper', 'init',
51+
'step_lambda_wrapper', 'flask_wrapper', 'log', 'error']
52+
53+
54+
# The modules are patched only if DISABLE_EPSAGON_PATCH variable is NOT 'TRUE'
55+
if os.environ.get('DISABLE_EPSAGON_PATCH') != 'TRUE':
56+
patch_all()

Diff for: epsagon/common.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Common objects"""
2+
3+
4+
class ErrorCode(object):
5+
"""
6+
Error codes enum
7+
"""
8+
OK = 0
9+
ERROR = 1
10+
EXCEPTION = 2
11+
12+
13+
class EpsagonWarning(Warning):
14+
"""
15+
An Epsagon warning.
16+
"""
17+
pass

Diff for: epsagon/constants.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""General constants"""
2+
3+
import os
4+
5+
__version__ = '1.0.0'
6+
7+
DEFAULT_REGION = 'us-east-1'
8+
REGION = os.environ.get('AWS_REGION', DEFAULT_REGION)
9+
10+
TRACE_COLLECTOR_URL = "{protocol}{region}.tc.epsagon.com"
11+
COLD_START = True
12+
13+
# How long we try to send traces.
14+
SEND_TIMEOUT = 1
15+
16+
MAX_MESSAGE_SIZE = 512

Diff for: epsagon/event.py

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""
2+
Base Event class
3+
"""
4+
5+
from __future__ import absolute_import
6+
import time
7+
from .common import ErrorCode
8+
9+
10+
class BaseEvent(object):
11+
"""
12+
Represents base trace's event
13+
"""
14+
15+
ORIGIN = 'base'
16+
RESOURCE_TYPE = 'base'
17+
18+
def __init__(self, start_time):
19+
"""
20+
Initialize.
21+
:param start_time: event's start time (epoch)
22+
"""
23+
24+
self.start_time = start_time
25+
self.event_id = ''
26+
self.origin = self.ORIGIN
27+
self.duration = 0.0
28+
self.error_code = ErrorCode.OK
29+
self.exception = {}
30+
31+
self.resource = {
32+
'type': self.RESOURCE_TYPE,
33+
'name': '',
34+
'operation': '',
35+
'metadata': {},
36+
}
37+
38+
@staticmethod
39+
def load_from_dict(event_data):
40+
"""
41+
Load Event object from dict.
42+
:param event_data: dict
43+
:return: Event
44+
"""
45+
46+
event = BaseEvent(event_data['start_time'])
47+
event.event_id = event_data['id']
48+
event.origin = event_data['origin']
49+
event.duration = event_data['duration']
50+
event.error_code = event_data['error_code']
51+
event.resource = event_data['resource']
52+
if event.error_code == ErrorCode.EXCEPTION:
53+
event.exception = event_data['exception']
54+
55+
return event
56+
57+
def to_dict(self):
58+
"""
59+
Converts Event to dict.
60+
:return: dict
61+
"""
62+
63+
self_as_dict = {
64+
'id': self.event_id,
65+
'start_time': self.start_time,
66+
'duration': self.duration,
67+
'origin': self.origin,
68+
'error_code': self.error_code,
69+
'resource': self.resource,
70+
}
71+
72+
if self.error_code == ErrorCode.EXCEPTION:
73+
self_as_dict['exception'] = self.exception
74+
75+
return self_as_dict
76+
77+
def terminate(self):
78+
"""
79+
Sets duration time.
80+
:return: None
81+
"""
82+
self.duration = time.time() - self.start_time
83+
84+
def set_error(self):
85+
"""
86+
Sets general error.
87+
:return: None
88+
"""
89+
90+
self.error_code = ErrorCode.ERROR
91+
92+
def set_exception(self, exception, traceback_data):
93+
"""
94+
Sets exception data on event.
95+
:param exception: Exception object
96+
:param traceback_data: traceback string
97+
:return: None
98+
"""
99+
100+
self.error_code = ErrorCode.EXCEPTION
101+
self.exception['type'] = type(exception).__name__
102+
self.exception['message'] = str(exception)
103+
self.exception['traceback'] = traceback_data
104+
self.exception['time'] = time.time()

Diff for: epsagon/events/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)