Skip to main content

Python Logging secured by blockchain

Project description

Logchain

pipeline status Dependencies license

Web page Package

Python Logging based on blockchain 📜 ⛓️.

Logs get chained

The current log line contains the signature of the previous line with your secret.

  • detect lines deleted / lost
  • detect logs tampering

Philosophy

The package is intended to be a lightweight util for generating incorruptible logs.

For this pupose we rely as much as possible on standard packages: few dependencies, high quality.

The formatters are easy extensible by simply deriving from Basic.

Usage

Install

pip install logchain

Choose your log type

Many types of logs are supported out-of-the-box:

  • Basic raw text, relying on the standard formatter
  • Json structured log lines with static & dynamic fields
  • CSV work in progress

You can write a custom formatter in 20-ish lines.

Init once in main

from logchain import LogChainer

# Initialize a default chainer.
theLogger = LogChainer()

# Register the formatter to the logger.
theLogger.initLogging()

Have a look at the comprehensive guide of constructor parameters.

Use everywhere with python logging module

import logging

logging.debug("My message")
logging.info("Some information")

Check your logs integrity afterwards

from logchain import LogChainer

aLogChain = [
	"2020-03-30 13:38:00.782|0ec90b9839fdd964|TestChaining.py:20 test_logging_happy_case hello gg",
	"2020-03-30 13:38:00.782|2e3f1b4a7b946fb1|TestChaining.py:21 test_logging_happy_case voila1",
	"2020-03-30 13:38:00.782|10d1ab606618492a|TestChaining.py:22 test_logging_happy_case voila2",
	"2020-03-30 13:38:00.782|805757e144f4e385|TestChaining.py:23 test_logging_happy_case voila5",
	"2020-03-30 13:38:00.782|3bda90b5af77d3fe|TestChaining.py:24 test_logging_happy_case voila4"
]
result = LogChainer.verify(aLogChain)

if not result:
	print("Last good line", result.prevLine)
	print("First bad line", result.line)
else:
	print("All right")

Constructor parameters

They are passed as a dict and/or named arguments.

from logchain import LogChainer

theLogger = LogChainer(verbosity = 3, secret = "mySignatureKey")

params = {"verbosity": 3, "secret": "mySignatureKey"}
theLogger = LogChainer(params, timestampFmt = "iso")
Param Default value Description
formatterCls formatters.Basic Type of logging to perform, raw text, json, custom
format see below Placeholder string used by raw-text loggers
secret secrets.token_urlsafe(128) Signature key to compute the line signature
seed secrets.token_urlsafe() Random string to sign into the first log line
timestampFmt "iso" iso for 8601 or strftime compatible placeholders
timestampPrecision "milliseconds" timespec element used by the datetime library
timestampUtc False Transform the timestamp to its value in UTC
stream cout Where the logs are sent, file/console/custom stream
verbosity 0 Number [0..5] mapped to a logging.level

The default format is %(timestamp)s %(levelLetters)s %(fileLine)-15s %(funcName)-15s %(message)-60s |%(signature)s. It relies on some extra fields like the signature at its end.

Logchain extra logging fields

We enrich the standard logging record with some handy fields:

Name Description
fileLine Widespread filename:lineno
levelLetters 4 first letters of logging level names: short and unambiguous
signature The digital signature of the previous line. Include it in all your lines to benefit from the chaining
timestamp Improved version of asctime, see below

The timestamp field offers more flexibility than asctime in regards to:

  • the precision; can go up to the micro seconds (msecs cannot)
  • the decimal separator; you choose, '.' by default
  • utc or local timezone
  • customize the format only in one place: timestampFmt

Dynamic logging fields

The package is suitable for server/app logging which context changes from one transaction to another. Here is an example of setting contextual information throughout the lifecycle of an app:

App.py

class App:
	def __init__(self, appName, logger):
		self.logger = logger
		self.logger.setField(appName = appName)
		logging.info("Creating the app")

	def handleTransaction(self, userId, callback):
		with self.logger.managedField(uId = userId, trxId = secrets.token_urlsafe(8)):
			callback()

	def close(self):
		logging.info("Closing the app")

Callbacks.py

	# The log chain in transparent for the callbacks
	def callback1():
		logging.warn("Something happened")

	def callback2():
		logging.info("Serving a resource")

main.py

def main():
	theLogger = logchain.LogChainer(formatterCls = logchain.formatters.Json)
	theLogger.initLogging()

	app = App("MyApp", theLogger)
	app.handleTransaction("user1", callback1)
	app.handleTransaction("user1", callback2)
	app.close()

You can either use:

  • setField: set a permanant field, remove it by setting it to None.
  • managedField: set a temporary field for the scope of the context manager.

Contributing

Install

Simply clone and submit pull requests.

Testing

The unit tests are located in the test folder which contains the __main__.py entrypoint.

# Run all
python test

# Get additional options
python test --help

Delivery

Use to the awesome Poetry tool for this purpose:

poetry build
poetry publish

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

logchain-0.1.2.tar.gz (8.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

logchain-0.1.2-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file logchain-0.1.2.tar.gz.

File metadata

  • Download URL: logchain-0.1.2.tar.gz
  • Upload date:
  • Size: 8.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.0.5 CPython/3.6.9 Linux/4.15.0-96-generic

File hashes

Hashes for logchain-0.1.2.tar.gz
Algorithm Hash digest
SHA256 06be513ebfdc7c8c8a9e5400aa70f4f1affa976a2ca8ac6a92e4921b0fcd0d40
MD5 6f0a99a28578e12eff996d554762fec5
BLAKE2b-256 e7ca844fe23b888ff02734a82bb6294ce6cf817193a6f0fd594d91cb65064ff5

See more details on using hashes here.

File details

Details for the file logchain-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: logchain-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.0.5 CPython/3.6.9 Linux/4.15.0-96-generic

File hashes

Hashes for logchain-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b93fa8b0d6c0e4848bd1ff825a00bd63e1b182f15e4f42e56e6a35a54455f927
MD5 9e2623de10ce68871ec6e246035ebc26
BLAKE2b-256 68616aa2b39dedb97b46873acb5e4ab675857eae7cddfcfe5f364832da9a0f4b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page