Skip to content

Commit 525c874

Browse files
author
tiagoepr
committed
Added daily file logging feature
1 parent 086b0c1 commit 525c874

5 files changed

Lines changed: 146 additions & 30 deletions

File tree

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ python setup.py install
7070
## Run as
7171
### Command Line
7272
```sh
73-
http2mllp localhost --mllp_port 2575
73+
http2mllp localhost
7474

7575
mllp2http http://localhost:8000
7676

77-
https2mllp localhost --mllp_port 2575
77+
https2mllp localhost
7878

7979
mllp2https https://localhost:8000
8080
```
@@ -99,11 +99,11 @@ docker build -t tiagoepr/mllp-https .
9999
Run as:
100100

101101
```sh
102-
docker run -it -p 8000:8000 --rm tiagoepr/mllp-https http2mllp host.docker.internal --mllp_port 2575
102+
docker run -it -p 8000:8000 --rm tiagoepr/mllp-https http2mllp host.docker.internal
103103

104104
docker run -it -p 2575:2575 --rm tiagoepr/mllp-https mllp2http http://host.docker.internal:8000
105105

106-
docker run -it -p 8000:8000 --rm tiagoepr/mllp-https https2mllp host.docker.internal --mllp_port 2575 (See note below about SSL certificate)
106+
docker run -it -p 8000:8000 --rm tiagoepr/mllp-https https2mllp host.docker.internal (See note below about SSL certificate)
107107

108108
docker run -it -p 2575:2575 --rm tiagoepr/mllp-https mllp2https https://host.docker.internal:8000
109109
```
@@ -117,7 +117,7 @@ docker cp [LOCAL/PATH/TO/ssl] [container_id]:/usr/local/lib/python3.10/site-pack
117117
where [LOCAL/PATH/TO/ssh] is the path for the folder containing the certfile.crt and keyfile.key and [container_id] should be replaced by the container ID which is running.
118118
<br>Now, on the container bash, run the command:
119119
```sh
120-
docker run -it -p 8000:8000 --rm tiagoepr/mllp-https https2mllp host.docker.internal --mllp_port 2575 --certfile /usr/local/lib/python3.7/site-packages/mllp_http_https/ssl/certfile.crt --keyfile /usr/local/lib/python3.7/site-packages/mllp_http_https/ssl/keyfile.key
120+
docker run -it -p 8000:8000 --rm tiagoepr/mllp-https https2mllp host.docker.internal --certfile /usr/local/lib/python3.7/site-packages/mllp_http_https/ssl/certfile.crt --keyfile /usr/local/lib/python3.7/site-packages/mllp_http_https/ssl/keyfile.key
121121
```
122122
## Usage
123123

@@ -192,7 +192,7 @@ environment variables:
192192

193193
### https2mllp
194194
```
195-
usage: https2mllp [-h] [-H HOST] [-p PORT] [--username USERNAME] [--password PASSWORD] [--keep-alive KEEP_ALIVE] [--log-level {error,warn,info}] [--log-file LOG_FILE] [--mllp-keep-alive MLLP_KEEP_ALIVE]
195+
usage: https2mllp [-h] [-H HOST] [-p PORT] [--username USERNAME] [--password PASSWORD] [--keep-alive KEEP_ALIVE] [--log-level {error,warn,info}] [--log-folder LOG_FOLDER] [--mllp-keep-alive MLLP_KEEP_ALIVE]
196196
[--mllp-max-messages MLLP_MAX_MESSAGES] [--mllp-release {1}] [--timeout TIMEOUT] [--content-type CONTENT_TYPE] [--mllp_port MLLP_PORT] [--certfile CERTFILE] [--keyfile KEYFILE] [--mllp_parser {True,False}] [-v]
197197
mllp_url
198198
@@ -214,7 +214,7 @@ optional arguments:
214214
--keep-alive KEEP_ALIVE
215215
keep-alive in milliseconds, or unlimited if -1. (default: 0)
216216
--log-level {error,warn,info}
217-
--log-file LOG_FILE Path to file where the logs will be placed. If not provided logging will be done on command window. (default: None)
217+
--log-folder LOG_FOLDER Path to folder where the logs will be placed. If not provided logging will be done on command window. (default: None)
218218
--mllp-keep-alive MLLP_KEEP_ALIVE
219219
keep-alive in milliseconds, or unlimited if -1. (default: 10000)
220220
--mllp-max-messages MLLP_MAX_MESSAGES
@@ -235,7 +235,7 @@ optional arguments:
235235
### mllp2https
236236

237237
```
238-
usage: mllp2https [-h] [-H HOST] [-p PORT] [--username USERNAME] [--password PASSWORD] [--content-type CONTENT_TYPE] [--log-level {error,warn,info}] [--log-file LOG_FILE] [--mllp-release {1}] [--timeout TIMEOUT] [--verify {False,True}]
238+
usage: mllp2https [-h] [-H HOST] [-p PORT] [--username USERNAME] [--password PASSWORD] [--content-type CONTENT_TYPE] [--log-level {error,warn,info}] [--log-folder LOG_FOLDER] [--mllp-release {1}] [--timeout TIMEOUT] [--verify {False,True}]
239239
[-v]
240240
https_url
241241
@@ -253,7 +253,7 @@ optional arguments:
253253
--content-type CONTENT_TYPE
254254
HTTPS Content-Type header (default: application/hl7-v2; charset=utf-8)
255255
--log-level {error,warn,info}
256-
--log-file LOG_FILE Path to file where the logs will be placed. If not provided logging will be done on command window. (default: None)
256+
--log-folder LOG_FOLDER Path to folder where the logs will be placed. If not provided logging will be done on command window. (default: None)
257257
--mllp-release {1} MLLP release version (default: 1)
258258
--timeout TIMEOUT Timeout in milliseconds (default: 0)
259259
--verify {False,True}

mllp_http_https/https2mllp.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@
1111
import ssl
1212
import threading
1313
import time
14-
from base64 import b64encode
1514
from datetime import datetime, timezone
1615

1716
from .mllp import send_mllp, parse_mllp
1817

1918
logger = logging.getLogger(__name__)
2019

21-
2220
class MllpClientOptions:
2321
def __init__(self, keep_alive, max_messages, timeout):
2422
# self.address = address
@@ -230,6 +228,7 @@ def do_POST(self):
230228

231229

232230
def serve(address, options, mllp_address, mllp_options):
231+
233232
# MLLP Client for dealing with the MLLP TCP connection
234233
client = MllpClient(mllp_address, mllp_options)
235234

mllp_http_https/log2file.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
### By Tiago Rodrigues
2+
### Sectra Iberia, Aug 2022
3+
### Script to manage the logging
4+
5+
6+
import logging
7+
import logging.handlers as handlers
8+
from time import sleep
9+
from threading import Thread
10+
import os
11+
import sys
12+
import datetime
13+
14+
15+
# Generates and manages the logs files
16+
class Log2File:
17+
def __init__(self, file_name, folder_path, log_level_str, number_of_days_log=1):
18+
self.file_name = file_name
19+
self.folder_path = folder_path
20+
self.log_level_str = log_level_str
21+
self.number_of_days_log = number_of_days_log
22+
23+
def log_level(self, arg):
24+
if arg == "error":
25+
return logging.ERROR
26+
elif arg == "warn":
27+
return logging.WARNING
28+
elif arg == "info":
29+
return logging.INFO
30+
31+
def new_log(self):
32+
formatter = logging.Formatter(
33+
fmt="%(asctime)s [%(levelname)s] %(name)s %(message)s"
34+
)
35+
level = self.log_level(self.log_level_str)
36+
37+
logger = logging.getLogger()
38+
logger.setLevel(level)
39+
40+
filename = self.folder_path + "\\" + self.file_name
41+
log_handler = handlers.TimedRotatingFileHandler(filename, when='D', interval=self.number_of_days_log)
42+
log_handler.setFormatter(formatter)
43+
44+
logger.addHandler(log_handler)
45+
46+
47+
# Looks and deletes old
48+
class LogMonitor:
49+
def __init__(self, number_of_days_check, folder_path):
50+
self.daemon = Thread(target=self.background_task, args=(number_of_days_check,), daemon=True, name='LogControl')
51+
self.folder_path = folder_path
52+
53+
# task that runs at a fixed interval
54+
def background_task(self, interval_days):
55+
interval_sec = interval_days * 24 * 60 * 60 # Days to sec
56+
57+
# run forever
58+
while True:
59+
# block for the interval
60+
sleep(interval_sec)
61+
62+
# perform the task
63+
N = interval_days
64+
if not os.path.exists(self.folder_path):
65+
print("Please provide valid path")
66+
sys.exit(1)
67+
if os.path.isfile(self.folder_path):
68+
print("Please provide dictionary path")
69+
sys.exit(2)
70+
today = datetime.datetime.now()
71+
for each_file in os.listdir(self.folder_path):
72+
if each_file[len(each_file) - 4:len(each_file)] != ".log":
73+
each_file_path = os.path.join(self.folder_path, each_file)
74+
if os.path.isfile(each_file_path):
75+
datetime_str = each_file[len(each_file) - 19:len(each_file)]
76+
77+
file_cre_date = datetime.datetime.strptime(datetime_str, '%Y-%m-%d_%H-%M-%S')
78+
# file_cre_date = datetime.datetime.fromtimestamp(os.path.getctime(each_file_path))
79+
80+
dif_days = (today - file_cre_date).days
81+
if dif_days > N:
82+
os.remove(each_file_path)
83+
print(each_file_path, dif_days)
84+
85+
def start(self):
86+
self.daemon.start()
87+
pass

mllp_http_https/main.py

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import argparse
22
import datetime
33
import logging
4+
import logging.handlers as handlers
45
import urllib.parse
5-
from .version import __version__
6+
from mllp_http_https.version import __version__
67

78

89
class ArgumentFormatter(
@@ -135,6 +136,7 @@ def http2mllp():
135136
pass
136137

137138

139+
138140
def mllp2http():
139141
parser = argparse.ArgumentParser(
140142
"mllp2http",
@@ -233,7 +235,7 @@ def https2mllp():
233235
)
234236
parser.add_argument(
235237
"--mllp_port",
236-
default=2575,
238+
default="2575",
237239
type=int,
238240
help="MLLP PORT",
239241
)
@@ -274,9 +276,9 @@ def https2mllp():
274276
default="info",
275277
)
276278
parser.add_argument(
277-
"--log-file",
279+
"--log-folder",
278280
default=None,
279-
help="Path to file where the logs will be placed. If not provided logging will be done on command window."
281+
help="Path to folder where the logs will be placed. If not provided logging will be done on command window."
280282
)
281283
parser.add_argument(
282284
"--mllp-keep-alive",
@@ -340,13 +342,24 @@ def https2mllp():
340342

341343
import mllp_http_https.https2mllp
342344

343-
# If log_file is provided, logs will be written in file. Otherwise, will be written on console.
344-
if args.log_file:
345-
logging.basicConfig(
346-
filename=args.log_file,
347-
format="%(asctime)s [%(levelname)s] %(name)s %(message)s",
348-
level=log_level(args.log_level),
345+
# If log_folder is provided, logs will be written in file. Otherwise, will be written on console.
346+
if args.log_folder:
347+
import mllp_http_https.log2file
348+
log = mllp_http_https.log2file.Log2File(
349+
file_name="https2mllp.log",
350+
folder_path=args.log_folder,
351+
log_level_str=args.log_level,
352+
number_of_days_log=1,
353+
)
354+
log.new_log()
355+
356+
# Start additional thread to delete old logs
357+
log_monitor = mllp_http_https.log2file.LogMonitor(
358+
number_of_days_check=30,
359+
folder_path=args.log_folder,
349360
)
361+
log_monitor.start()
362+
350363
else:
351364
logging.basicConfig(
352365
format="%(asctime)s [%(levelname)s] %(name)s %(message)s",
@@ -370,6 +383,7 @@ def https2mllp():
370383
)
371384

372385
try:
386+
# Start the serving on the main thread
373387
mllp_http_https.https2mllp.serve(
374388
address=(
375389
args.host,
@@ -435,9 +449,9 @@ def mllp2https():
435449
default="info",
436450
)
437451
parser.add_argument(
438-
"--log-file",
452+
"--log-folder",
439453
default=None,
440-
help="Path to file where the logs will be placed. If not provided logging will be done on command window."
454+
help="Path to folder where the logs will be placed. If not provided logging will be done on command window."
441455
)
442456
parser.add_argument(
443457
"--mllp-release",
@@ -466,13 +480,29 @@ def mllp2https():
466480

467481
import mllp_http_https.mllp2https
468482

469-
# If log_file is provided, logs will be written in file. Otherwise, will be written on console.
470-
if args.log_file:
471-
logging.basicConfig(
472-
filename=args.log_file,
473-
format="%(asctime)s [%(levelname)s] %(name)s %(message)s",
474-
level=log_level(args.log_level),
483+
# If log_folder is provided, logs will be written in file. Otherwise, will be written on console.
484+
if args.log_folder:
485+
import mllp_http_https.log2file
486+
log = mllp_http_https.log2file.Log2File(
487+
file_name="mllp2https.log",
488+
folder_path=args.log_folder,
489+
log_level_str=args.log_level,
490+
number_of_days_log=1,
475491
)
492+
log.new_log()
493+
494+
# Start additional thread to delete old logs
495+
log_monitor = mllp_http_https.log2file.LogMonitor(
496+
number_of_days_check=30,
497+
folder_path=args.log_folder,
498+
)
499+
log_monitor.start()
500+
501+
# logging.basicConfig(
502+
# filename=args.log_file,
503+
# format="%(asctime)s [%(levelname)s] %(name)s %(message)s",
504+
# level=log_level(args.log_level),
505+
# )
476506
else:
477507
logging.basicConfig(
478508
format="%(asctime)s [%(levelname)s] %(name)s %(message)s",

mllp_http_https/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.2.35"
1+
__version__ = "1.2.36"

0 commit comments

Comments
 (0)