Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117884722
logger.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None
logger.py
View Options
# -*- coding: utf-8 -*-
# Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com)
#
# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from
__future__
import
print_function
import
grp
import
logging
import
logging.handlers
import
os
import
pwd
import
sys
class
StderrToLogger
:
"""
Fake file-like stream object that redirects writes to a logger instance.
"""
def
__init__
(
self
,
logger
,
log_level
=
logging
.
DEBUG
):
self
.
logger
=
logger
self
.
log_level
=
log_level
self
.
linebuf
=
''
self
.
skip_next
=
False
def
write
(
self
,
buf
):
# ugly patch to make smtplib and smtpd debug logging records appear on one line in log file
# smtplib uses "print>>stderr, var, var" statements for debug logging. These
# statements are splited into separate lines on separating whitespace.
for
line
in
buf
.
rstrip
()
.
splitlines
():
if
self
.
skip_next
:
self
.
skip_next
=
False
continue
if
buf
!=
'
\n
'
:
linestarts
=
line
.
split
(
':'
)[
0
]
if
linestarts
in
[
'send'
,
'reply'
,
'Data'
,
'recips'
,
'Peer'
,
'sender'
]:
self
.
linebuf
=
line
elif
linestarts
.
startswith
(
'===>'
):
# Do not log lines starting with ====>
self
.
linebuf
=
''
self
.
skip_next
=
True
continue
else
:
self
.
logger
.
log
(
self
.
log_level
,
'
%s
%s
'
,
self
.
linebuf
,
line
.
rstrip
()[:
150
])
self
.
linebuf
=
''
def
flush
(
self
):
pass
class
LoggerAdapter
(
logging
.
LoggerAdapter
):
"""
Custom LoggingAdapter to log Wallace mail message Queue ID
"""
def
process
(
self
,
msg
,
kwargs
):
return
'
%s
%s
'
%
(
self
.
extra
[
'qid'
],
msg
),
kwargs
class
Logger
(
logging
.
Logger
):
"""
The PyKolab version of a logger.
This class wraps the Python native logging library, adding to the
loglevel capabilities, a debuglevel capability.
"""
debuglevel
=
0
fork
=
False
loglevel
=
logging
.
CRITICAL
process_username
=
'kolab'
process_groupname
=
'kolab-n'
if
hasattr
(
sys
,
'argv'
):
for
arg
in
sys
.
argv
:
if
debuglevel
==
-
1
:
try
:
debuglevel
=
(
int
)(
arg
)
except
ValueError
:
continue
loglevel
=
logging
.
DEBUG
break
if
arg
==
'-d'
:
debuglevel
=
-
1
continue
if
arg
==
'-l'
:
loglevel
=
-
1
continue
if
arg
==
'--fork'
:
fork
=
True
if
loglevel
==
-
1
:
if
hasattr
(
logging
,
arg
.
upper
()):
loglevel
=
getattr
(
logging
,
arg
.
upper
())
else
:
loglevel
=
logging
.
DEBUG
if
arg
in
[
'-u'
,
'--user'
]:
process_username
=
-
1
continue
if
arg
.
startswith
(
'--user='
):
process_username
=
arg
.
split
(
'='
)[
1
]
if
process_username
==
-
1
:
process_username
=
arg
if
arg
in
[
'-g'
,
'--group'
]:
process_groupname
=
-
1
continue
if
arg
.
startswith
(
'--group='
):
process_groupname
=
arg
.
split
(
'='
)[
1
]
if
process_groupname
==
-
1
:
process_groupname
=
arg
# pylint: disable=too-many-branches
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
def
__init__
(
self
,
*
args
,
**
kw
):
if
'name'
in
kw
:
name
=
kw
[
'name'
]
elif
len
(
args
)
==
1
:
name
=
args
[
0
]
else
:
name
=
'pykolab'
logging
.
Logger
.
__init__
(
self
,
name
)
plaintextformatter
=
logging
.
Formatter
(
"
%(asctime)s
%(name)s
%(levelname)s
[
%(process)d
]
%(message)s
"
)
if
not
self
.
fork
:
self
.
console_stdout
=
logging
.
StreamHandler
(
sys
.
stdout
)
self
.
console_stdout
.
setFormatter
(
plaintextformatter
)
self
.
addHandler
(
self
.
console_stdout
)
if
'logfile'
in
kw
:
self
.
logfile
=
kw
[
'logfile'
]
else
:
self
.
logfile
=
'/var/log/kolab/pykolab.log'
group_gid
=
0
user_uid
=
0
# Make sure (read: attempt to change) the permissions
try
:
try
:
(
ruid
,
_
,
_
)
=
os
.
getresuid
()
(
rgid
,
_
,
_
)
=
os
.
getresgid
()
except
AttributeError
:
ruid
=
os
.
getuid
()
rgid
=
os
.
getgid
()
if
ruid
==
0
:
# Means we can setreuid() / setregid() / setgroups()
if
rgid
==
0
:
# Get group entry details
try
:
(
_
,
_
,
group_gid
,
_
)
=
grp
.
getgrnam
(
self
.
process_groupname
)
except
KeyError
:
group_gid
=
False
if
ruid
==
0
:
# Means we haven't switched yet.
try
:
(
_
,
_
,
user_uid
,
_
,
_
,
_
,
_
)
=
pwd
.
getpwnam
(
self
.
process_username
)
except
KeyError
:
user_uid
=
False
if
os
.
path
.
isfile
(
self
.
logfile
):
try
:
if
user_uid
>
0
or
group_gid
>
0
:
os
.
chown
(
self
.
logfile
,
user_uid
,
group_gid
)
os
.
chmod
(
self
.
logfile
,
0
o660
)
except
Exception
as
errmsg
:
self
.
error
(
_
(
"Could not change permissions on
%s
:
%r
"
)
%
(
self
.
logfile
,
errmsg
)
)
if
self
.
debuglevel
>
8
:
import
traceback
traceback
.
print_exc
()
except
Exception
as
errmsg
:
if
os
.
path
.
isfile
(
self
.
logfile
):
self
.
error
(
_
(
"Could not change permissions on
%s
:
%r
"
)
%
(
self
.
logfile
,
errmsg
))
if
self
.
debuglevel
>
8
:
import
traceback
traceback
.
print_exc
()
# Make sure the log file exists
try
:
fhandle
=
open
(
self
.
logfile
,
'a'
)
try
:
os
.
utime
(
self
.
logfile
,
None
)
finally
:
fhandle
.
close
()
try
:
filelog_handler
=
logging
.
FileHandler
(
filename
=
self
.
logfile
)
filelog_handler
.
setFormatter
(
plaintextformatter
)
except
IOError
as
errmsg
:
print
(
_
(
"Cannot log to file
%s
:
%s
"
)
%
(
self
.
logfile
,
errmsg
),
file
=
sys
.
stderr
)
if
len
(
self
.
handlers
)
<=
1
:
try
:
self
.
addHandler
(
filelog_handler
)
except
Exception
:
pass
except
IOError
:
pass
def
remove_stdout_handler
(
self
):
if
not
self
.
fork
:
self
.
console_stdout
.
close
()
self
.
removeHandler
(
self
.
console_stdout
)
# pylint: disable=arguments-differ
# pylint: disable=keyword-arg-before-vararg
def
debug
(
self
,
msg
,
level
=
1
,
*
args
,
**
kw
):
self
.
setLevel
(
self
.
loglevel
)
# Work around other applications not using various levels of debugging
if
not
self
.
name
.
startswith
(
'pykolab'
)
and
self
.
debuglevel
!=
9
:
return
if
level
<=
self
.
debuglevel
:
self
.
log
(
logging
.
DEBUG
,
msg
)
logging
.
setLoggerClass
(
Logger
)
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Mon, Apr 6, 1:37 AM (3 d, 6 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18735213
Default Alt Text
logger.py (8 KB)
Attached To
Mode
rP pykolab
Attached
Detach File
Event Timeline