Skip to content

Commit ebb42a0

Browse files
committed
Basic project setup
1 parent 01f314d commit ebb42a0

12 files changed

+314
-145
lines changed

.gitignore

+14-131
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,4 @@
11
# Created by .ignore support plugin (hsz.mobi)
2-
### Backup template
3-
*.bak
4-
*.gho
5-
*.ori
6-
*.orig
7-
*.tmp
8-
9-
### Vim template
10-
# Swap
11-
[._]*.s[a-v][a-z]
12-
[._]*.sw[a-p]
13-
[._]s[a-rt-v][a-z]
14-
[._]ss[a-gi-z]
15-
[._]sw[a-p]
16-
17-
# Session
18-
Session.vim
19-
Sessionx.vim
20-
21-
# Temporary
22-
.netrwhist
23-
*~
24-
# Auto-generated tag files
25-
tags
26-
# Persistent undo
27-
[._]*.un~
28-
29-
### Go template
30-
# Binaries for programs and plugins
31-
*.exe
32-
*.exe~
33-
*.dll
34-
*.so
35-
*.dylib
36-
37-
# Test binary, built with `go test -c`
38-
*.test
39-
40-
# Output of the go coverage tool, specifically when used with LiteIDE
41-
*.out
42-
43-
# Dependency directories (remove the comment below to include it)
44-
# vendor/
45-
462
### Python template
473
# Byte-compiled / optimized / DLL files
484
__pycache__/
@@ -169,6 +125,20 @@ dmypy.json
169125
# Pyre type checker
170126
.pyre/
171127

128+
### VirtualEnv template
129+
# Virtualenv
130+
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
131+
.Python
132+
[Bb]in
133+
[Ii]nclude
134+
[Ll]ib
135+
[Ll]ib64
136+
[Ll]ocal
137+
[Ss]cripts
138+
pyvenv.cfg
139+
.venv
140+
pip-selfcheck.json
141+
172142
### Linux template
173143
*~
174144

@@ -184,57 +154,6 @@ dmypy.json
184154
# .nfs files are created when an open file is removed but is still being accessed
185155
.nfs*
186156

187-
### Emacs template
188-
# -*- mode: gitignore; -*-
189-
*~
190-
\#*\#
191-
/.emacs.desktop
192-
/.emacs.desktop.lock
193-
*.elc
194-
auto-save-list
195-
tramp
196-
.\#*
197-
198-
# Org-mode
199-
.org-id-locations
200-
*_archive
201-
202-
# flymake-mode
203-
*_flymake.*
204-
205-
# eshell files
206-
/eshell/history
207-
/eshell/lastdir
208-
209-
# elpa packages
210-
/elpa/
211-
212-
# reftex files
213-
*.rel
214-
215-
# AUCTeX auto folder
216-
/auto/
217-
218-
# cask packages
219-
.cask/
220-
dist/
221-
222-
# Flycheck
223-
flycheck_*.el
224-
225-
# server auth directory
226-
/server/
227-
228-
# projectiles files
229-
.projectile
230-
231-
# directory configuration
232-
.dir-locals.el
233-
234-
# network security
235-
/network-security.data
236-
237-
238157
### macOS template
239158
# General
240159
.DS_Store
@@ -263,39 +182,6 @@ Network Trash Folder
263182
Temporary Items
264183
.apdisk
265184

266-
### VisualStudioCode template
267-
.vscode/*
268-
!.vscode/settings.json
269-
!.vscode/tasks.json
270-
!.vscode/launch.json
271-
!.vscode/extensions.json
272-
273-
### Windows template
274-
# Windows thumbnail cache files
275-
Thumbs.db
276-
Thumbs.db:encryptable
277-
ehthumbs.db
278-
ehthumbs_vista.db
279-
280-
# Dump file
281-
*.stackdump
282-
283-
# Folder config file
284-
[Dd]esktop.ini
285-
286-
# Recycle Bin used on file shares
287-
$RECYCLE.BIN/
288-
289-
# Windows Installer files
290-
*.cab
291-
*.msi
292-
*.msix
293-
*.msm
294-
*.msp
295-
296-
# Windows shortcuts
297-
*.lnk
298-
299185
### JetBrains template
300186
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
301187
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
@@ -307,9 +193,6 @@ $RECYCLE.BIN/
307193
# CMake
308194
cmake-build-*/
309195

310-
# Mongo Explorer plugin
311-
.idea/**/mongoSettings.xml
312-
313196
# File-based project format
314197
*.iws
315198

.prospector.yaml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
strictness: high
2+
test-warnings: true
3+
doc-warnings: false
4+
5+
ignore-paths:
6+
- build
7+
- .git
8+
- __pycache__
9+
- .eggs
10+
- dist
11+
- .tox
12+
- .cachedocs
13+
14+
pep8:
15+
options:
16+
max-line-length: 120
17+
18+
mccabe:
19+
max-complexity: 10
20+
21+
pylint:
22+
run: false
23+
24+
pyroma:
25+
run: false
26+
27+
frosted:
28+
run: false
29+
30+
vulture:
31+
run: false
32+
33+
pep257:
34+
run: false

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright 2016-2019 The FIAAS Authors
189+
Copyright 2017 FINN.no AS
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

README.md

-13
This file was deleted.

README.rst

Whitespace-only changes.

fiaas_logging/__init__.py

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8
3+
4+
# Copyright 2017-2019 The FIAAS Authors
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
from __future__ import absolute_import
18+
19+
import threading
20+
import datetime
21+
import json
22+
import logging
23+
import sys
24+
25+
__version__ = '0.1.0'
26+
LOG_EXTRAS = threading.local()
27+
28+
29+
class FiaasFormatter(logging.Formatter):
30+
UNWANTED = (
31+
"msg", "args", "exc_info", "exc_text", "levelno", "created", "msecs", "relativeCreated", "funcName",
32+
"filename", "lineno", "module")
33+
RENAME = {
34+
"levelname": "level",
35+
"threadName": "thread",
36+
"name": "logger",
37+
}
38+
39+
def format(self, record):
40+
fields = vars(record).copy()
41+
fields["@timestamp"] = self.format_time(record)
42+
fields["@version"] = 1
43+
fields["LocationInfo"] = self._build_location(fields)
44+
fields["message"] = record.getMessage()
45+
fields["extras"] = getattr(record, "extras", {})
46+
if "exc_info" in fields and fields["exc_info"]:
47+
fields["throwable"] = self.formatException(fields["exc_info"])
48+
for original, replacement in self.RENAME.items():
49+
fields[replacement] = fields.pop(original)
50+
for unwanted in self.UNWANTED:
51+
fields.pop(unwanted)
52+
return json.dumps(fields, default=self._default_json_default)
53+
54+
@staticmethod
55+
def format_time(record):
56+
"""ELK is strict about it's timestamp, so use more strict ISO-format"""
57+
dt = datetime.datetime.fromtimestamp(record.created)
58+
return dt.isoformat()
59+
60+
@staticmethod
61+
def _default_json_default(obj):
62+
"""
63+
Coerce everything to strings.
64+
All objects representing time get output as ISO8601.
65+
"""
66+
if isinstance(obj, (datetime.datetime, datetime.date, datetime.time)):
67+
return obj.isoformat()
68+
else:
69+
return str(obj)
70+
71+
@staticmethod
72+
def _build_location(fields):
73+
return {
74+
"method": fields["funcName"],
75+
"file": fields["filename"],
76+
"line": fields["lineno"],
77+
"module": fields["module"]
78+
}
79+
80+
81+
class ExtraFilter(logging.Filter):
82+
def filter(self, record):
83+
extras = {}
84+
for key, value in vars(LOG_EXTRAS).items():
85+
extras[key] = value
86+
record.extras = extras
87+
return 1
88+
89+
90+
def set_extras(**kwargs):
91+
for key, value in kwargs.items():
92+
setattr(LOG_EXTRAS, key, value)
93+
94+
95+
def init_logging(debug=False, format="plain"):
96+
"""Set up logging system, according to best practice for cloud
97+
98+
:param debug: Enable debug logging
99+
:param format: Select log format. Available options are "json" and "plain".
100+
"""
101+
root = logging.getLogger()
102+
root.setLevel(logging.INFO)
103+
if debug:
104+
root.setLevel(logging.DEBUG)
105+
root.addHandler(_create_default_handler(format))
106+
107+
108+
def _create_default_handler(format):
109+
handler = logging.StreamHandler(sys.stdout)
110+
handler.addFilter(ExtraFilter())
111+
if _json_format(format):
112+
handler.setFormatter(FiaasFormatter())
113+
elif _plain_format(format):
114+
handler.setFormatter(logging.Formatter("[%(asctime)s|%(levelname)7s] %(message)s [%(name)s|%(threadName)s]"))
115+
return handler
116+
117+
118+
def _json_format(format):
119+
return format == "json"
120+
121+
122+
def _plain_format(format):
123+
return format == "plain"

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-e .[dev]

setup.cfg

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[aliases]
2+
test=pytest
3+
4+
[tool:pytest]
5+
addopts = --junitxml=build/reports/tests/junit.xml --cov=fiaas_logging --cov-report html --cov-report term --cov-report xml
6+
7+
[coverage:html]
8+
directory=build/reports/coverage
9+
10+
[coverage:xml]
11+
output=build/reports/coverage.xml

0 commit comments

Comments
 (0)