Package: network-statistics-service
Network Statistics ServiceThis repository contains a small python package which generates network statistics. It has built-in functionality to upload those statistics to a DynamoDB table but also provides an interface which can be implemented to publish this statistics to a service of your choice.InstallationThis package can be installed withpip install network-statistics-service.Implementation DetailsThe package uses a command line executor to run thepingcommand for latency statistics and thespeedtestcomand (included in the package) for speed statistics.UsageThe following is a basic example in which network statistics are returned as a dictionary.from NetworkStatisticsService.statistics_service import StatisticsService

if  __name__ == "__main__":
    statistics_service = StatisticsService()
    stats = statistics_service.generate_statistics()Thestatsvariable will store a dictionary similar to the following:{'Loss': 0.0, 'Min': 24.244, 'Avg': 24.679, 'Max': 25.293, 'Stddev': 0.455, 'Download': 184.79, 'Upload': 280.34, 'Timestamp': 1591373792}. The keys are ofstringtype and the values are offloattype.In case of an error, the returned dictionary will contain a timestamp and a string with the error message.Disabling certain statisticsIf your application does not need either the latency or the speed statistics, they can be individually disabled using the following properties on theStatisticsServiceobject.speed_statistics_enabled- defaults toTrue;latency_statistics_enabled- defaults toTrue.In the following example, the speed statistics are disabled.from NetworkStatisticsService.statistics_service import StatisticsService

if  __name__ == "__main__":
    statistics_service = StatisticsService()
    statistics_service.speed_statistics_enabled = False
    stats = statistics_service.generate_statistics()In this case, thestatsdictionary will look like this:{'Loss': 0.0, 'Min': 20.366, 'Avg': 24.064, 'Max': 26.564, 'Stddev': 2.925, 'Timestamp': 1591374439}.Configuring the ping countBy default, the service runs thepingcommand with a count of 20. This default value can be provided to the constructor:statistics_service = StatisticsService(default_ping_count=10)In this case, all subsequent calls to thegenerate_statisticsmethod will use a ping count of 10.Another way of changing the ping count is on each call togenerate_statistics:stats = statistics_service.generate_statistics(override_ping_count=5). This value overrides the value provided in the constructor.Uploading the Network StatisticsTheStatisticsServicealso provides means to upload the statistics dictionary and error logs. It comes with built-in functionality to upload to DynamoDB.Configuring the StatisticsService for DynamoDB UploadYou can opt to upload either the statistics or the error logs, or both. This behaviour is controlled by the following properties of theStatisticsServiceobject:stats_upload_enabled- defaults toFalse;logs_upload_enabled- defaults toFalse.Setting your AWS CredentialsCredentials have to be provided via named profiles in credential files. Please checkthis documentationfor information on how to achieve that.DynamoDB Table RequirementsIn order for the service to function, your DynamoDB table configuration must be able to support the generated data. Your DynamoDB table should have one configured property as hash key calledTimestamp. If you use Terraform for provisioning infrastructure, you can usethis fileas an example.Providing DynamoDB Information to the Statistics ServiceThe configuration is passed to theStatisticsServiceobject via theDynamoDBConfigobject. It provides the following properties:aws_profile- the AWS profile (from the credential files) to use. Defaults todefault;aws_region- the AWS region in which your DynamoDB tables reside. Mandatory field.stats_table- the name of the DynamoDB table where statistics should be uploaded. Required only ifstats_upload_enabledis set toTrue.logs_table- the name of the DynamoDB table where error logs should be uploaded. Required only iflogs_upload_enabledis set toTrue.The following example shows how to use the DynamoDB upload functionality.from NetworkStatisticsService.statistics_service import StatisticsService
from NetworkStatisticsService.dynamo_db_config import DynamoDBConfig

if  __name__ == "__main__":
    statistics_service = StatisticsService()
    dynamo_config = DynamoDBConfig(aws_region="eu-central-1", 
								   stats_table="stats-table",
								   logs_table="logs-table")
    statistics_service.stats_upload_enabled = True
    statistics_service.logs_upload_enabled = True
    statistics_service.dynamo_db_config = dynamo_config
    statistics_service.generate_statistics()In case the DynamoDB configuration is not valid, thegenerate_statisticsmethod will raise an exception of typeDynamoDbException.Providing TimeToLive ConfigurationThe configuration is passed to theDynamoDBConfigobject via theTtlConfigobject. It provides the following properties:time_in_months- the time in months the object should reside in the DynamoDB Table. Month is considered a 31 day period.attribute_name- the attribute name is the name of the attribute configured in DynamoDB as the TTL attribute.Thetime_in_monthsshould be a positive number, and theattribute_nameshould be a non-empty string. Providing values that do not match this
criteria will result in the constructor raising aValueException.The following example shows how to use the DynamoDB upload functionality with TTL Config.from NetworkStatisticsService.statistics_service import StatisticsService
from NetworkStatisticsService.dynamo_db_config import DynamoDBConfig
from NetworkStatisticsService.ttl_config import TtlConfig

if  __name__ == "__main__":
    statistics_service = StatisticsService()
    dynamo_config = DynamoDBConfig(aws_region="eu-central-1", 
								   stats_table="stats-table",
								   logs_table="logs-table")
    ttl_config = TtlConfig(1, "TimeToLive")
    dynamo_config.ttl_config = ttl_config
    statistics_service.stats_upload_enabled = True
    statistics_service.logs_upload_enabled = True
    statistics_service.dynamo_db_config = dynamo_config
    statistics_service.generate_statistics()Implementing your own Statistics UploaderThe service provides the possibility of implementing a custom class which can be provided to theStatisticsServiceobject to be used in place of the built-in DynamoDB uploader.Your class must implement theInformalStatisticUploaderInterfaceprovided in the package. The object can be passed to theStatisticsServicevia the constructor. The following example demonstrates implementing a custom class for upload.from NetworkStatisticsService.statistics_service import StatisticsService
from NetworkStatisticsService.informal_statistics_uploader import InformalStatisticUploaderInterface

class CustomStatisticsUploader(InformalStatisticUploaderInterface):
    def upload_statistics(self, stats_dict: dict):
	    print(stats_dict)

	def upload_logs(self, logs_dict: dict):
		pass


if  __name__ == "__main__":
	custom_stats_uploader = CustomStatisticsUploader()
	statistics_service = StatisticsService(stats_uploader=custom_stats_uploader)
	statistics_service.stats_upload_enabled = True
	statistics_service.generate_statistics()If your custom class does not implement the interface, theStatisticsServiceconstructor will raise an exception of typeValueError.CommentsIf you have any questions regarding this Python package, do not hesitate tocontact me.