HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonflaskMinor

How to better indent multiline strings with many string formatting args?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
formattingmultilinewithbetterargsmanyhowstringsstringindent

Problem

I have a function, that is used in flask, for logging application errors:

def log_exception(self, exc_info):
        self.logger.error('''
Time:                 %s
Path:                 %s
HTTP Method:          %s
POST_ARGS:            %s
GET_ARGS:             %s
Client IP Address:    %s
User Agent:           %s
User Platform:        %s
User Browser:         %s
User Browser Version: %s
Username:             %s
Email:                %s''' % (
               datetime.now(),
               request.path,
               request.method,
               request.form,
               request.args,
               request.remote_addr,
               request.user_agent.string,
               request.user_agent.platform,
               request.user_agent.browser,
               request.user_agent.version,
               current_user,
               getattr(current_user, 'email', 'no email'),
        ), exc_info=exc_info)


As you can see the indentation is quite ugly and the long list of formatting args makes it even worse.

Using textwrap.dedent helped the situation, but the formatting args is still problematic:

```
def log_exception(self, exc_info):
self.logger.error(
dedent('''Time: %s
Path: %s
HTTP Method: %s
POST_ARGS: %s
GET_ARGS: %s
Client IP Address: %s
User Agent: %s
User Platform: %s
User Browser: %s
User Browser Version: %s
Username: %s
Email: %s''') % (datetime.now(),
request.path,
request.method,
request.form,
request.args,

Solution

How about this?

def log_exception(self, exc_info):

    msg = ''

    msg += 'Time:                 %s\n' % datetime.now()
    msg += 'Path:                 %s\n' % request.path
    msg += 'HTTP Method:          %s\n' % request.method
    msg += 'POST_ARGS:            %s\n' % request.form
    msg += 'GET_ARGS:             %s\n' % request.args
    msg += 'Client IP Address:    %s\n' % request.remote_addr
    msg += 'User Agent:           %s\n' % request.user_agent.string
    msg += 'User Platform:        %s\n' % request.user_agent.platform
    msg += 'User Browser:         %s\n' % request.user_agent.browser
    msg += 'User Browser Version: %s\n' % request.user_agent.version
    msg += 'Username:             %s\n' % current_user
    msg += 'Email:                %s\n' % getattr(current_user, 'email', 'no email')

    self.logger.error(msg, exc_info=exc_info)


I guess, logging an exception doesn't happen every often, so efficiency shouldn't be a concern.

Alternatively, you can emulate variable interpolation and avoid formatting altogether:

now = datetime.now()    
email = getattr(current_user, 'email', 'no email')

msg = _('''\
    Time:                 {now}
    Path:                 {request.path}
    HTTP Method:          {request.method}
    POST_ARGS:            {request.form}
    GET_ARGS:             {request.args}
    Client IP Address:    {request.remote_addr}
    User Agent:           {request.user_agent.string}
    User Platform:        {request.user_agent.platform}
    User Browser:         {request.user_agent.browser}
    User Browser Version: {request.user_agent.version}
    Username:             {current_user}
    Email:                {email}
''')

self.logger.error(dedent(msg), exc_info=exc_info)

Code Snippets

def log_exception(self, exc_info):

    msg = ''

    msg += 'Time:                 %s\n' % datetime.now()
    msg += 'Path:                 %s\n' % request.path
    msg += 'HTTP Method:          %s\n' % request.method
    msg += 'POST_ARGS:            %s\n' % request.form
    msg += 'GET_ARGS:             %s\n' % request.args
    msg += 'Client IP Address:    %s\n' % request.remote_addr
    msg += 'User Agent:           %s\n' % request.user_agent.string
    msg += 'User Platform:        %s\n' % request.user_agent.platform
    msg += 'User Browser:         %s\n' % request.user_agent.browser
    msg += 'User Browser Version: %s\n' % request.user_agent.version
    msg += 'Username:             %s\n' % current_user
    msg += 'Email:                %s\n' % getattr(current_user, 'email', 'no email')

    self.logger.error(msg, exc_info=exc_info)
now = datetime.now()    
email = getattr(current_user, 'email', 'no email')

msg = _('''\
    Time:                 {now}
    Path:                 {request.path}
    HTTP Method:          {request.method}
    POST_ARGS:            {request.form}
    GET_ARGS:             {request.args}
    Client IP Address:    {request.remote_addr}
    User Agent:           {request.user_agent.string}
    User Platform:        {request.user_agent.platform}
    User Browser:         {request.user_agent.browser}
    User Browser Version: {request.user_agent.version}
    Username:             {current_user}
    Email:                {email}
''')

self.logger.error(dedent(msg), exc_info=exc_info)

Context

StackExchange Code Review Q#60919, answer score: 3

Revisions (0)

No revisions yet.