feat(Features): 🚩 Begin development of Hidden Dragon
corrected parsing of log level (sort of), beginning work on implementing Hidden Dragon.
This commit is contained in:
parent
a79cd2e5e9
commit
4418d3c65d
12 changed files with 294 additions and 28 deletions
21
Docs/User_Docs.md
Normal file
21
Docs/User_Docs.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2024 Anoduck
|
||||||
|
This software is released under the MIT License.
|
||||||
|
https://opensource.org/licenses/MIT
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Crouching Tiger User Documentation
|
||||||
|
|
||||||
|
**Hazaa! You made it to the docs!**
|
||||||
|
|
||||||
|
## Forward
|
||||||
|
|
||||||
|
Out dear little program finally grew to the point where it was felt that more thorough documentation
|
||||||
|
was a neccessity. Personally, yours truly, has always been frustrated with projects where the
|
||||||
|
doccumentation is lacking in substance. Thankfully, I am rather long winded, literorically speaking.
|
||||||
|
So, if my attention span holds up, this should be something worth while.
|
||||||
|
|
||||||
|
What set aside the original AT&T Unix from other operating systems of the time was Dennis Ritchie's
|
||||||
|
unwavering dedication to thoroughly well-written documentation, and project transparency. As also
|
||||||
|
the creator of the "C" programming language, Ritchie created most of the codebase for modern
|
||||||
|
computing. We should all keep the importance of documentation in mind in our endeavours.
|
1
__version__.py
Normal file
1
__version__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
__version__ = '0.4.3'
|
|
@ -9,6 +9,20 @@
|
||||||
#+EXPORT_EXCLUDE_TAGS: noexport
|
#+EXPORT_EXCLUDE_TAGS: noexport
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
* Changelog
|
* Changelog
|
||||||
|
** unreleased
|
||||||
|
*** 2024.02.22
|
||||||
|
- Reconfigured logging to allow dynamic level setting
|
||||||
|
- Setup log to Rotate using logging.handlers.RotateLogging (or something like that.)
|
||||||
|
- Created HDragon class in preparation for creation of hidden_dragon module.
|
||||||
|
- Created apData class in hidden_dragon module.
|
||||||
|
- added scapy-fakeap to project workspace for reference.
|
||||||
|
- Created TapIf for hidden_dragon
|
||||||
|
- Created __main__ for hdragon.
|
||||||
|
- Began to add hdragon parameters to config file.
|
||||||
|
- Created native banner for ctiger, art no longer needed.
|
||||||
|
- Created banner for hdragon, art still no longer needed.
|
||||||
|
- added argparse condiguration for hdragon.
|
||||||
|
- ctiger passes args to hdragon class and displays cute message.
|
||||||
** 0.4.3
|
** 0.4.3
|
||||||
*** 2024.02.13
|
*** 2024.02.13
|
||||||
- Setup own awkward Semver solution, not too pleased
|
- Setup own awkward Semver solution, not too pleased
|
||||||
|
|
|
@ -2,11 +2,15 @@
|
||||||
"folders": [
|
"folders": [
|
||||||
{
|
{
|
||||||
"path": "."
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../scapy-fakeap"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
"conventionalCommits.scopes": [
|
"conventionalCommits.scopes": [
|
||||||
"Structure"
|
"Structure",
|
||||||
|
"Features"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
from art.art import tprint
|
|
||||||
from configobj import ConfigObj, validate
|
from configobj import ConfigObj, validate
|
||||||
from .proclog import ProcLog
|
from .proclog import ProcLog
|
||||||
from .mac_purge import Purge
|
from .mac_purge import Purge
|
||||||
from .attack import Attack
|
from .attack import Attack
|
||||||
|
from .hdragon import Dragon
|
||||||
from semver import Version
|
from semver import Version
|
||||||
from .__version__ import version as _version
|
from .__version__ import version as _version
|
||||||
|
|
||||||
|
@ -38,12 +38,23 @@ use_daemon = boolean(default=False)
|
||||||
|
|
||||||
# -----------------------------------------------------------
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
# Mac Purge Setings
|
# Mac Purge Settings
|
||||||
# -----------------
|
# -----------------
|
||||||
[MAC_PURGE]
|
[MAC_PURGE]
|
||||||
if_type = option('create', 'switch', default='switch')
|
if_type = option('create', 'switch', default='switch')
|
||||||
valid_results = string(default='ct_valid.csv')
|
valid_results = string(default='ct_valid.csv')
|
||||||
channel_list = list(default=list(1, 6, 11))
|
channel_list = list(default=list(1, 6, 11))
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
# Hidden Dragon Settings
|
||||||
|
# -----------------------
|
||||||
|
[DRAGON]
|
||||||
|
if_type = option('create', 'switch', default='switch')
|
||||||
|
ap_iface = string(default='mon0')
|
||||||
|
ap_db = string(default='ap_database.csv')
|
||||||
|
dragon_results = string(default='dragon_results.csv')
|
||||||
|
# -----------------------------------------------------------
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,7 +71,7 @@ class ProcArgs:
|
||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
alog = ProcLog()
|
alog = ProcLog()
|
||||||
log = alog.get_log(args.log_file)
|
log = alog.get_log(args.log_file, args.log_level)
|
||||||
log.info('Started crouching tiger')
|
log.info('Started crouching tiger')
|
||||||
log.info('Started logger...')
|
log.info('Started logger...')
|
||||||
match args.module:
|
match args.module:
|
||||||
|
@ -73,8 +84,6 @@ class ProcArgs:
|
||||||
log=log)
|
log=log)
|
||||||
case "mac":
|
case "mac":
|
||||||
log.info('Beginning Mac Purge')
|
log.info('Beginning Mac Purge')
|
||||||
#mon_dev, mon_type, valid_file, channels
|
|
||||||
#mon_dev, mon_type, valid_file, channels
|
|
||||||
log.debug('args: {0}'.format(args))
|
log.debug('args: {0}'.format(args))
|
||||||
global valid_file
|
global valid_file
|
||||||
valid_file = args.valid_file
|
valid_file = args.valid_file
|
||||||
|
@ -84,6 +93,15 @@ class ProcArgs:
|
||||||
valid_file=args.valid_file,
|
valid_file=args.valid_file,
|
||||||
channels=args.channels,
|
channels=args.channels,
|
||||||
log=log)
|
log=log)
|
||||||
|
case "dragon":
|
||||||
|
log.info('Beginning Hidden Dragon')
|
||||||
|
log.debug('args: {0}'.format(args))
|
||||||
|
dragon = Dragon()
|
||||||
|
dragon.hidden_dragon(mon_type=args.mon_type,
|
||||||
|
ap_iface=args.ap_iface,
|
||||||
|
ap_db=args.ap_db,
|
||||||
|
results=args.results,
|
||||||
|
log=log)
|
||||||
case _:
|
case _:
|
||||||
ap.print_help()
|
ap.print_help()
|
||||||
|
|
||||||
|
@ -106,7 +124,11 @@ class ProcArgs:
|
||||||
- None
|
- None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
tprint('Crouching Tiger', font='tarty3')
|
print("""
|
||||||
|
░█▀▀█ █▀▀█ █▀▀█ █──█ █▀▀ █──█ ─▀─ █▀▀▄ █▀▀▀ ▀▀█▀▀ ─▀─ █▀▀▀ █▀▀ █▀▀█
|
||||||
|
░█─── █▄▄▀ █──█ █──█ █── █▀▀█ ▀█▀ █──█ █─▀█ ─░█── ▀█▀ █─▀█ █▀▀ █▄▄▀
|
||||||
|
░█▄▄█ ▀─▀▀ ▀▀▀▀ ─▀▀▀ ▀▀▀ ▀──▀ ▀▀▀ ▀──▀ ▀▀▀▀ ─░█── ▀▀▀ ▀▀▀▀ ▀▀▀ ▀─▀▀
|
||||||
|
""")
|
||||||
|
|
||||||
# This script must be run as root!
|
# This script must be run as root!
|
||||||
if not os.geteuid() == 0:
|
if not os.geteuid() == 0:
|
||||||
|
@ -171,11 +193,14 @@ class ProcArgs:
|
||||||
'\n'
|
'\n'
|
||||||
'There are three types of actions that can be performed:\n'
|
'There are three types of actions that can be performed:\n'
|
||||||
'\n'
|
'\n'
|
||||||
'2. ATTACK [att] = Will run a scan in the background looking for aps in target list.\n'
|
'1. ATTACK [att] = Will run a scan in the background looking for aps in target list.\n'
|
||||||
' If found will begin capturing a pcap file and deauth attack.\n'
|
' If found will begin capturing a pcap file and deauth attack.\n'
|
||||||
'\n'
|
'\n'
|
||||||
'3. Mac_Purge [mac] = Experimental: Scans for wireless devices and acquires their MAC\n' ' addresses. Then transmits a Clear to Send Frame. If the device responds with \n'
|
'2. Mac_Purge [mac] = Experimental: Scans for wireless devices and acquires their MAC\n' ' addresses. Then transmits a Clear to Send Frame. If the device responds with \n'
|
||||||
' data frame, then information on the device will be stored and written to file.\n'
|
' data frame, then information on the device will be stored and written to file.\n'
|
||||||
|
'\n'
|
||||||
|
'3. Hidden_Dragon [dragon] = Experimental: Creates a "evil twin" access point\n'
|
||||||
|
'from which various attack vectors can be leverages.\n'
|
||||||
'\n')
|
'\n')
|
||||||
# options parser
|
# options parser
|
||||||
ap.add_argument('-v', '--version', action='version',
|
ap.add_argument('-v', '--version', action='version',
|
||||||
|
@ -213,6 +238,7 @@ class ProcArgs:
|
||||||
# help='Run in daemon mode.')
|
# help='Run in daemon mode.')
|
||||||
att_parse.set_defaults(fun=Attack.attack)
|
att_parse.set_defaults(fun=Attack.attack)
|
||||||
|
|
||||||
|
# mac parse subcommands
|
||||||
mac_parse = subparse.add_parser('mac', help='Grab Valid addresses')
|
mac_parse = subparse.add_parser('mac', help='Grab Valid addresses')
|
||||||
mac_parse.add_argument('-t', '--type', dest='mon_type',
|
mac_parse.add_argument('-t', '--type', dest='mon_type',
|
||||||
choices=['create', 'switch'],
|
choices=['create', 'switch'],
|
||||||
|
@ -226,6 +252,22 @@ class ProcArgs:
|
||||||
help='A single or comma seperated list of channels.')
|
help='A single or comma seperated list of channels.')
|
||||||
mac_parse.set_defaults(fun=Purge.mac_revealer)
|
mac_parse.set_defaults(fun=Purge.mac_revealer)
|
||||||
|
|
||||||
|
# Dragon Subcommands
|
||||||
|
hd_parse = subparse.add_parser('dragon', help='Perform Dragon')
|
||||||
|
hd_parse.add_argument('-t', '--type', dest='mon_type',
|
||||||
|
choices=['create', 'switch'],
|
||||||
|
default=config['DRAGON']['if_type'],
|
||||||
|
help='Create new monitor inf or switch mode.')
|
||||||
|
hd_parse.add_argument('-a', '--ap_iface', dest='ap_iface',
|
||||||
|
default=config['DRAGON']['ap_iface'],
|
||||||
|
help='Interface to use for AP')
|
||||||
|
hd_parse.add_argument('-d', '--ap_db', dest='ap_db',
|
||||||
|
default=config['DRAGON']['ap_db'],
|
||||||
|
help='Database file of APs')
|
||||||
|
hd_parse.add_argument('-r', '--results', dest='results',
|
||||||
|
default=config['DRAGON']['dragon_results'],
|
||||||
|
help='File to write results too.')
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# parse the args #
|
# parse the args #
|
||||||
##################
|
##################
|
||||||
|
|
44
ctiger/hdragon.py
Normal file
44
ctiger/hdragon.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Copyright (c) 2024 Anoduck
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
# from .hidden_dragon import __main__
|
||||||
|
|
||||||
|
|
||||||
|
class Dragon:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
print("""
|
||||||
|
______ __ __ ______ ______ ______
|
||||||
|
/\ ___\ /\ "-.\ \ /\__ _\ /\ ___\ /\ == \
|
||||||
|
\ \ __\ \ \ \-. \ \/_/\ \/ \ \ __\ \ \ __<
|
||||||
|
\ \_____\ \ \_\\"\_\ \ \_\ \ \_____\ \ \_\ \_\
|
||||||
|
\/_____/ \/_/ \/_/ \/_/ \/_____/ \/_/ /_/
|
||||||
|
|
||||||
|
______ __ __ ______
|
||||||
|
/\__ _\ /\ \_\ \ /\ ___\
|
||||||
|
\/_/\ \/ \ \ __ \ \ \ __\
|
||||||
|
\ \_\ \ \_\ \_\ \ \_____\
|
||||||
|
\/_/ \/_/\/_/ \/_____/
|
||||||
|
|
||||||
|
) (
|
||||||
|
( /( ( ( )\ )
|
||||||
|
)\()) ( )\ ) )\ ) ( (()/( ( ) ( (
|
||||||
|
((_)\ )\ (()/( (()/( ))\ ( /(_)) )( ( /( )\))( ( (
|
||||||
|
_((_)((_) ((_)) ((_))/((_) )\ ) (_))_ (()\ )(_))((_))\ )\ )\ )
|
||||||
|
| || | (_) _| | _| |(_)) _(_/( | \ ((_)((_)_ (()(_)((_) _(_/(
|
||||||
|
| __ | | |/ _` |/ _` |/ -_)| ' \)) | |) || '_|/ _` |/ _` |/ _ \| ' \))
|
||||||
|
|_||_| |_|\__,_|\__,_|\___||_||_| |___/ |_| \__,_|\__, |\___/|_||_|
|
||||||
|
|___/
|
||||||
|
""")
|
||||||
|
|
||||||
|
def hidden_dragon(self, mon_type, ap_iface, ap_db, results, log):
|
||||||
|
log.info('Starting Hidden Dragon')
|
||||||
|
print("""
|
||||||
|
You have configured Hidden Dragon to run with these options:
|
||||||
|
mon_type: {0}
|
||||||
|
ap_iface: {1}
|
||||||
|
ap_db: {2}
|
||||||
|
results: {3}
|
||||||
|
Have a good day, and thanks for all the fish!
|
||||||
|
""".format(mon_type, ap_iface, ap_db, results))
|
5
ctiger/hidden_dragon/__init__.py
Normal file
5
ctiger/hidden_dragon/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Copyright (c) 2024 Anoduck
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
15
ctiger/hidden_dragon/__main__.py
Normal file
15
ctiger/hidden_dragon/__main__.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright (c) 2024 Anoduck
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
from .data import apData
|
||||||
|
from .mk_inf import TunIf
|
||||||
|
|
||||||
|
|
||||||
|
def main(ap, log):
|
||||||
|
iface = TunIf(ap=ap, apData=apData, log=log)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(ap, log)
|
12
ctiger/hidden_dragon/ap.py
Normal file
12
ctiger/hidden_dragon/ap.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (c) 2024 Anoduck
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
from scapy.all import sniff
|
||||||
|
from time import time, sleep
|
||||||
|
from scapy.layers.dot11 import RadioTap, conf as scapyconf
|
||||||
|
from scapy.layers.inet import TCP
|
||||||
|
|
||||||
|
|
44
ctiger/hidden_dragon/data.py
Normal file
44
ctiger/hidden_dragon/data.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Copyright (c) 2024 Anoduck
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from random import choice
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class apData:
|
||||||
|
dns_servers: list = ["8.8.8.8", "9.9.9.9", "1.1.1.1",
|
||||||
|
"208.67.222.222", "208.67.220.220",
|
||||||
|
"8.26.56.26", "8.20.247.20", "89.0.142.86"]
|
||||||
|
DEFAULT_DNS_SERVER: str = choice(dns_servers)
|
||||||
|
RSN: str = "\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x28\x00"
|
||||||
|
|
||||||
|
AP_WLAN_TYPE_OPEN: int = 0
|
||||||
|
AP_WLAN_TYPE_WPA: int = 1
|
||||||
|
AP_WLAN_TYPE_WPA2: int = 2
|
||||||
|
AP_WLAN_TYPE_WPA_WPA2: int = 3
|
||||||
|
AP_AUTH_TYPE_OPEN: int = 0
|
||||||
|
AP_AUTH_TYPE_SHARED: int = 1
|
||||||
|
AP_RATES: str = "\x0c\x12\x18\x24\x30\x48\x60\x6c"
|
||||||
|
|
||||||
|
DOT11_MTU: int = 4096
|
||||||
|
|
||||||
|
DOT11_TYPE_MANAGEMENT: int = 0
|
||||||
|
DOT11_TYPE_CONTROL: int = 1
|
||||||
|
DOT11_TYPE_DATA: int = 2
|
||||||
|
|
||||||
|
DOT11_SUBTYPE_DATA: int = 0x00
|
||||||
|
DOT11_SUBTYPE_PROBE_REQ: int = 0x04
|
||||||
|
DOT11_SUBTYPE_AUTH_REQ: int = 0x0B
|
||||||
|
DOT11_SUBTYPE_ASSOC_REQ: int = 0x00
|
||||||
|
DOT11_SUBTYPE_REASSOC_REQ: int = 0x02
|
||||||
|
DOT11_SUBTYPE_QOS_DATA: int = 0x28
|
||||||
|
|
||||||
|
IFNAMSIZ: int = 16
|
||||||
|
IFF_TUN: int = 0x0001
|
||||||
|
IFF_TAP: int = 0x0002 # Should we want to tunnel layer 2...
|
||||||
|
IFF_NO_PI: int = 0x1000
|
||||||
|
TUNSETIFF: int = 0x400454ca
|
||||||
|
IP_ADDRESS: str = "10.0.0.2"
|
60
ctiger/hidden_dragon/mk_inf.py
Normal file
60
ctiger/hidden_dragon/mk_inf.py
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# Copyright (c) 2024 Anoduck
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
import fcntl
|
||||||
|
import struct
|
||||||
|
import os
|
||||||
|
import threading
|
||||||
|
import subprocess
|
||||||
|
from scapy.layers.inet import IP
|
||||||
|
from .data import apData
|
||||||
|
from ctiger import NetDev
|
||||||
|
|
||||||
|
|
||||||
|
class TunIf(threading.Thread):
|
||||||
|
def __init__(self, ap, apData, name="fakeap", log):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
|
self.apData = apData
|
||||||
|
self.log = log
|
||||||
|
|
||||||
|
if len(name) > apData.IFNAMSIZ:
|
||||||
|
raise Exception(
|
||||||
|
"Tun interface name cannot be larger than " + str(apData.IFNAMSIZ))
|
||||||
|
|
||||||
|
self.name = name
|
||||||
|
self.setDaemon(True)
|
||||||
|
self.ap = ap
|
||||||
|
|
||||||
|
# Virtual interface
|
||||||
|
self.fd = open('/dev/net/tun', 'r+b')
|
||||||
|
ifr_flags = apData.IFF_TUN | apData.IFF_NO_PI # Tun device without packet information
|
||||||
|
ifreq = struct.pack('16sH', name, ifr_flags)
|
||||||
|
fcntl.ioctl(self.fd, apData.TUNSETIFF, ifreq) # Syscall to create interface
|
||||||
|
|
||||||
|
# Assign IP and bring interface up
|
||||||
|
# set_ip_address(name, self.ap.ip)
|
||||||
|
# def set_ip_address(dev, ip):
|
||||||
|
if subprocess.call(['ip', 'addr', 'add', apData.ip, 'dev', apData.dev]):
|
||||||
|
print("Failed to assign IP address {} to {}.".format(apData.ip, apData.dev))
|
||||||
|
if subprocess.call(['ip', 'link', 'set', 'dev', apData.dev, 'up']):
|
||||||
|
print("Failed to bring device %s up." % dev, Level.CRITICAL)
|
||||||
|
|
||||||
|
print("Created TUN interface %s at %s. Bind it to your services as needed." % (
|
||||||
|
name, self.ap.ip))
|
||||||
|
|
||||||
|
def write(self, pkt):
|
||||||
|
os.write(self.fd.fileno(), str(pkt[IP])) # Strip layer 2
|
||||||
|
|
||||||
|
def read(self):
|
||||||
|
raw_packet = os.read(self.fd.fileno(), apData.DOT11_MTU)
|
||||||
|
return raw_packet
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
os.close(self.fd.fileno())
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
raw_packet = self.read()
|
||||||
|
self.ap.callbacks.cb_tint_read(raw_packet)
|
|
@ -4,34 +4,38 @@
|
||||||
# https://opensource.org/licenses/MIT
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from logging import handlers
|
||||||
|
from warnings import warn
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class ProcLog:
|
class ProcLog:
|
||||||
|
|
||||||
def get_log(self, log_file,):
|
def get_log(self, log_file, lev):
|
||||||
self.log_file = log_file
|
self.log_file = log_file
|
||||||
lev = 'debug'
|
self.lev = 'debug'
|
||||||
rot = True
|
|
||||||
if not os.path.exists(log_file):
|
if not os.path.exists(log_file):
|
||||||
open(log_file, 'a').close()
|
open(log_file, 'a').close()
|
||||||
if rot:
|
log = logging.getLogger(__name__)
|
||||||
log_size = os.path.getsize(log_file)
|
|
||||||
smart_size = log_size % 1024
|
|
||||||
if smart_size >= 1024:
|
|
||||||
os.remove(log_file)
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
if log.hasHandlers():
|
if log.hasHandlers():
|
||||||
log.handlers.clear()
|
log.handlers.clear()
|
||||||
if lev == 'info':
|
log_levels = {'info': logging.INFO,
|
||||||
log.setLevel(logging.INFO)
|
'debug': logging.DEBUG,
|
||||||
elif lev == 'debug':
|
'error': logging.ERROR}
|
||||||
|
if lev in log_levels.keys():
|
||||||
|
set_level = log_levels[lev]
|
||||||
|
log.setLevel(set_level)
|
||||||
|
else:
|
||||||
|
warn('Invalid level. Defaulting to debug')
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
handler = logging.FileHandler(log_file, mode='a', encoding='utf-8')
|
handler = handlers.RotatingFileHandler(filename=log_file,
|
||||||
formatter = logging.Formatter(
|
mode='a', maxBytes=1024,
|
||||||
'%(asctime)s - %(levelname)s - %(message)s')
|
backupCount=2, encoding='utf-8',
|
||||||
handler.setFormatter(formatter)
|
delay=False)
|
||||||
log.addHandler(handler)
|
formatter = logging.Formatter(
|
||||||
log.info('started motion detection')
|
'%(asctime)s - %(levelname)s - %(message)s')
|
||||||
log.info('Acquired Logger')
|
handler.setFormatter(formatter)
|
||||||
|
log.addHandler(handler)
|
||||||
|
log.info('started motion detection')
|
||||||
|
log.info('Acquired Logger')
|
||||||
return log
|
return log
|
||||||
|
|
Loading…
Reference in a new issue