Compare commits

...
25 Commits
Author SHA1 Message Date
Brian Bjarke Jensen d13e069287 Merge pull request 'added separate flush interval' (#13) from main into release
Docker / Test (push) Successful in 39s
Docker / Publish (push) Successful in 13s
Reviewed-on: http://192.168.1.2:3000/brian/bandwidth_probing/pulls/13
2023-07-12 14:16:02 +02:00
brb bc0d2aced7 updated flake8 outputs
pipeline / Test (push) Successful in 39s
2023-07-12 14:11:35 +02:00
brb d872cfde43 flake8 compliant 2023-07-12 14:11:05 +02:00
brb 7a396a88fb updated workflow
pipeline / Test (push) Failing after 34s
2023-07-12 14:08:51 +02:00
brb 238188f4a5 introduced flake8 error 2023-07-12 14:08:37 +02:00
brb 63975169c0 mypy compliant
pipeline / Test (push) Successful in 38s
2023-07-12 14:04:10 +02:00
brb 387986e2d8 flake8 compliant 2023-07-12 14:03:41 +02:00
brb d5bcf04e61 updated readme
pipeline / Test (push) Failing after 38s
2023-07-12 14:01:06 +02:00
brb 12ccd1e586 added extra data flushing event with separate trigger time 2023-07-12 13:59:53 +02:00
brb e3fadbc22c added data_queue flush interval 2023-07-12 13:47:56 +02:00
brb ecfddfc69e added data_queue flush interval 2023-07-12 13:47:37 +02:00
brb caeace7907 updated to check for env var USER_ID 2023-07-12 13:46:01 +02:00
brb a456ccc536 updated to check for env var USER_ID 2023-07-12 13:35:40 +02:00
brb ae26182e23 updated default values 2023-07-12 13:26:12 +02:00
brb 652fe9af3a added checking for environment variables 2023-07-12 13:17:12 +02:00
Brian Bjarke Jensen 1760fc8136 Merge pull request 'added data queue' (#9) from main into release
Docker / Publish (push) Successful in 13s
Docker / Test (push) Successful in 39s
Reviewed-on: http://192.168.1.2:3000/brian/bandwidth_probing/pulls/9
2023-07-12 12:59:05 +02:00
brb cffcac8b37 added data queue
pipeline / Test (push) Successful in 39s
2023-07-12 12:54:52 +02:00
brb 907958484c removed unused step
pipeline / Test (push) Successful in 39s
Docker / Test (push) Successful in 39s
Docker / Publish (push) Successful in 8s
2023-07-12 12:08:42 +02:00
brb 9a1724742a added code to extract version number
Docker / Test (push) Successful in 39s
Docker / Publish (push) Successful in 7s
2023-07-12 11:54:31 +02:00
brb 20023ca9a9 added code to print version number
Docker / Publish (push) Failing after 6s
Docker / Test (push) Successful in 39s
2023-07-12 11:49:00 +02:00
brb 478d258a31 added code to extract version number
Docker / Test (push) Successful in 40s
Docker / Publish (push) Failing after 7s
2023-07-12 11:45:18 +02:00
brb eb8b1456ab added code to extract version number
Docker / Test (push) Successful in 40s
Docker / Publish (push) Failing after 5s
2023-07-12 11:39:44 +02:00
brb 4c99b6a1af testing how to set env vars
Docker / Test (push) Successful in 38s
Docker / Publish (push) Failing after 4s
2023-07-12 11:32:50 +02:00
brb 0becddf81f added code to extract version number
Docker / Test (push) Successful in 38s
Docker / Publish (push) Failing after 5s
2023-07-12 11:29:26 +02:00
brb 233c0ef977 added code to extract version number
Docker / Test (push) Successful in 40s
Docker / Publish (push) Failing after 5s
2023-07-12 11:27:46 +02:00
7 changed files with 151 additions and 72 deletions
+1 -25
View File
@@ -23,30 +23,6 @@ jobs:
pip install flake8 mypy pytest pip install flake8 mypy pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: PEP8 check - name: PEP8 check
run: flake8 ./code --benchmark --exit-zero run: flake8 ./code --benchmark
- name: Type check - name: Type check
run: mypy ./code run: mypy ./code
# publish:
# name: Publish
# runs-on: ubuntu-latest
# needs: [test]
# if: gitea.ref == 'refs/heads/release'
# env:
# repository_host: 192.168.1.2:5000
# repository_name: ${{ gitea.repository }}
# repository_version: v1.0
# steps:
# - uses: actions/checkout@v3
# - name: Build
# run: |
# echo "> docker build . --file Dockerfile --tag ${repository_name}:${repository_version}"
# docker build . --file Dockerfile --tag ${repository_name}:${repository_version}
# - name: Tag
# run: |
# echo "> docker tag ${repository_name}:${repository_version} ${repository_host}/${repository_name}:${repository_version}"
# docker tag ${repository_name}:${repository_version} ${repository_host}/${repository_name}:${repository_version}
# - name: Push
# run: |
# echo "> docker push ${repository_host}/${repository_name}:${repository_version}"
# docker push ${repository_host}/${repository_name}:${repository_version}
+11 -8
View File
@@ -22,7 +22,7 @@ jobs:
pip install flake8 mypy pytest pip install flake8 mypy pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: PEP8 check - name: PEP8 check
run: flake8 ./code --benchmark --exit-zero run: flake8 ./code --benchmark
- name: Type check - name: Type check
run: mypy ./code run: mypy ./code
publish: publish:
@@ -33,17 +33,20 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- -
name: Set Environment Variables name: Set Environment Variables
id: vars
env:
repository: ${{gitea.repository}}
ref_name: ${{gitea.ref_name}}
run: | run: |
echo "$GITEA_REF" echo $repository
echo "TAG=${GITEA_REF#refs/*/}" >> $gitea echo ::set-output name=OWNER::${repository#/*}
- echo ::set-output name=PROJECT::${repository#*/}
name: Show Environment Variables echo $ref_name
run: | echo ::set-output name=TAG::${ref_name#refs/*/}
echo "$gitea.TAG"
- -
name: Push Image name: Push Image
uses: docker/build-push-action@v2 uses: docker/build-push-action@v2
with: with:
context: . context: .
push: true push: true
tags: 192.168.1.2:5000/${{gitea.repository}}:${{steps.get_version.outputs.VERSION}} tags: 192.168.1.2:5000/${{gitea.repository}}:${{steps.vars.outputs.TAG}}
+18
View File
@@ -1,3 +1,21 @@
# bandwidth_probing # bandwidth_probing
Service that runs in a container and measures network bandwidth at a specified interval. The results are sent to a MongoDB database. Logs are sent to discord channel. Service that runs in a container and measures network bandwidth at a specified interval. The results are sent to a MongoDB database. Logs are sent to discord channel.
## Environment Variables
```python
LOGGER_LEVEL: Literal['debug', 'info', 'warning', 'error', 'critical'] = 'debug'
USER_ID: int = 0 # id number 0 is reserved for testing
REPLICATES: int = 3 # number of replicates to be measured per event
TRIGGER_INTERVAL_SECONDS: float = 3600 # seconds between events
DATA_QUEUE_FLUSH_INTERVAL_SECONDS: float = 600 # seconds between attempts to push data stuck in data queue
DB_IP_ADDRESS: str = '192.168.1.2'
DB_NAME: str = 'bandwidth_probing'
DB_COLLECTION_NAME: str = 'data'
DISCORD_SERVICE_NAME: str = 'bandwidth_probing
DISCORD_WEBHOOK_URL: str = 'https://discord.com/api/webhooks/1127970367047225354/wNkoRex4OncMw11OCJg6atR_xgHS2VhLrku4jYIUw81Kr4sutdD3Tt-XAltG0UQy14rZ'
DISCORD_LOGGER_LEVEL: Literal['debug', 'info', 'warning', 'error', 'critical'] = 'warning'
```
+15
View File
@@ -3,6 +3,7 @@ from dotenv import load_dotenv
from configparser import ConfigParser from configparser import ConfigParser
from pathlib import Path from pathlib import Path
import logging import logging
import os
# load default values # load default values
@@ -21,6 +22,20 @@ def connect(
""" """
Connect to MongoDB database and return collection. Connect to MongoDB database and return collection.
""" """
# load environment variables
load_dotenv()
ip_addr = os.getenv(
'DB_IP_ADDRESS',
default=DB_IP_ADDRESS
)
db_name = os.getenv(
'DB_NAME',
default=DB_NAME
)
collection_name = os.getenv(
'DB_COLLECTION_NAME',
default=DB_COLLECTION_NAME
)
# connect to database # connect to database
client: MongoClient = MongoClient(ip_addr) client: MongoClient = MongoClient(ip_addr)
db = client[db_name] db = client[db_name]
+3 -2
View File
@@ -1,8 +1,9 @@
[main] [main]
logger_level=info logger_level=debug
user_id=0 user_id=0
replicates=3 replicates=3
trigger_interval_seconds=60 trigger_interval_seconds=3600
data_queue_flush_interval_seconds=600
[database] [database]
db_ip_address=192.168.1.2 db_ip_address=192.168.1.2
+7 -1
View File
@@ -20,13 +20,18 @@ def initialise_app(
discord_service_name: str = DISCORD_SERVICE_NAME, discord_service_name: str = DISCORD_SERVICE_NAME,
discord_webhook_url: str = DISCORD_WEBHOOK_URL, discord_webhook_url: str = DISCORD_WEBHOOK_URL,
discord_logger_level: str = DISCORD_LOGGER_LEVEL discord_logger_level: str = DISCORD_LOGGER_LEVEL
): ) -> None:
""" """
Convienience function that ensures eveything is ready Convienience function that ensures eveything is ready
before running the main loop. before running the main loop.
""" """
# load environment variables # load environment variables
load_dotenv() load_dotenv()
assert (
'USER_ID' in os.environ
), (
'environment variable USER_ID must be specified'
)
logger_level = os.getenv( logger_level = os.getenv(
'LOGGER_LEVEL', 'LOGGER_LEVEL',
default=LOGGER_LEVEL default=LOGGER_LEVEL
@@ -58,6 +63,7 @@ def initialise_app(
level = getattr(logging, discord_logger_level.upper()) level = getattr(logging, discord_logger_level.upper())
discord_handler.setLevel(level=level) discord_handler.setLevel(level=level)
logger.addHandler(discord_handler) logger.addHandler(discord_handler)
logging.debug('finished')
if __name__ == '__main__': if __name__ == '__main__':
+93 -33
View File
@@ -1,8 +1,10 @@
import time import time
import logging import logging
import os import os
import json
from configparser import ConfigParser from configparser import ConfigParser
from pathlib import Path from pathlib import Path
from queue import Queue
from initialise_app import initialise_app from initialise_app import initialise_app
from bandwidth import measure as measure_bandwidth from bandwidth import measure as measure_bandwidth
from database import connect from database import connect
@@ -12,67 +14,125 @@ from database import connect
config = ConfigParser() config = ConfigParser()
config.read(Path(__file__).parent / 'defaults.ini') config.read(Path(__file__).parent / 'defaults.ini')
REPLICATES = int(config.get('main', 'replicates')) REPLICATES = int(config.get('main', 'replicates'))
USER_ID = int(config.get('main', 'user_id'))
TRIGGER_INTERVAL_SECONDS = float( TRIGGER_INTERVAL_SECONDS = float(
config.get( config.get(
'main', 'main',
'trigger_interval_seconds' 'trigger_interval_seconds'
) )
) )
DATA_QUEUE_FLUSH_INTERVAL_SECONDS = float(
config.get(
'main',
'data_queue_flush_interval_seconds'
)
)
def event( def flush_data(
replicates: int = REPLICATES, data_queue: Queue,
user_id: int = USER_ID user_id: int
): ) -> None:
logging.debug('started event') # connect to database
# load environment variables
replicates = int(os.getenv('REPLICATES', default=REPLICATES))
user_id = int(os.getenv('USER_ID', default=USER_ID))
# setup database connection
db = connect() db = connect()
# run event # flush queue
for rep_num in range(replicates): queue_size = data_queue.qsize()
logging.info(f'running replicate {rep_num}') for i in range(queue_size):
# do measurement # get data
try: data = data_queue.get()
res = measure_bandwidth() # prepare payload
except Exception as e:
logging.error(f'failed to measure bandwidth: {e}')
continue
# upload result to database
payload_dict = { payload_dict = {
'user_id': user_id, 'user_id': user_id,
'data': res 'data': data
} }
# send to database
try: try:
db_id = db.insert_one(payload_dict).inserted_id db_id = db.insert_one(payload_dict).inserted_id
except Exception as e: except Exception as e:
logging.error(f'failed sending results to database: {e}') logging.error('failed sending data to database')
logging.info(
'failed pushing to database:\n'
f'{json.dumps(payload_dict, indent=4)}\n'
f'with error: {e}'
)
data_queue.put(data) # put data back in queue
continue continue
logging.debug(f'data sent to database received db_id: {db_id}') else:
logging.debug(f'data sent to database received id: {db_id}')
logging.debug('finished')
def event(
data_queue: Queue,
user_id: int,
replicates: int = REPLICATES
) -> None:
# run event
for rep_num in range(replicates):
logging.debug(f'running replicate {rep_num+1} of {replicates}')
# do measurement
try:
data = measure_bandwidth()
except Exception as e:
logging.error(f'failed to measure bandwidth: {e}')
continue
# add data to queue
data_queue.put(data)
# polite pause
time.sleep(1) time.sleep(1)
# flush queue
if data_queue.qsize() > 0:
flush_data(
data_queue=data_queue,
user_id=user_id
)
logging.debug('finished') logging.debug('finished')
if __name__ == '__main__': if __name__ == '__main__':
# setup
initialise_app() initialise_app()
trigger_time = time.time() user_id = int(os.getenv('USER_ID', default=0))
while True: replicates = int(os.getenv('REPLICATES', default=REPLICATES))
if time.time() >= trigger_time:
# set new trigger time
trigger_interval = float( trigger_interval = float(
os.getenv( os.getenv(
'TRIGGER_INTERVAL_SECONDS', 'TRIGGER_INTERVAL_SECONDS',
default=TRIGGER_INTERVAL_SECONDS default=TRIGGER_INTERVAL_SECONDS
) )
) )
data_flush_interval = float(
os.getenv(
'DATA_QUEUE_FLUSH_INTERVAL_SECONDS',
default=DATA_QUEUE_FLUSH_INTERVAL_SECONDS
)
)
data_queue: Queue = Queue()
# start main loop
trigger_time = time.time()
data_flush_time = trigger_time + data_flush_interval
while True:
# measure event
if time.time() >= trigger_time:
logging.debug('triggered event')
# set new trigger time
trigger_time += trigger_interval trigger_time += trigger_interval
# run event # run event
try: event(
event() data_queue=data_queue,
except Exception as e: user_id=user_id,
logging.error(e) replicates=replicates
else: )
logging.info('finished event') # extra data flush
if (
time.time() >= data_flush_time and
data_queue.qsize() > 0
):
logging.debug('triggered extra data flush')
# set new trigger time
data_flush_time += data_flush_interval
# flush data
flush_data(
data_queue=data_queue,
user_id=user_id
)
# polite pause
time.sleep(1) time.sleep(1)