7

I'm using locust to stress test our app.

I'm getting errors because the POST call seems incorrect. Where can I see the logs for locust? I'd like to see what the post call looks like to see what's wrong.

Here's my code in case someone can tell me what I'm doing wrong:

from locust import HttpLocust, TaskSet, task

json3 = """{"stack_name": "beenz-php-app-12", "disable_rollback": true, "template": "php", "timeout_mins": 60}"""

class MyTaskSet(TaskSet):
    @task
    def send(self):
             response = self.client.post("/stacks", json3, headers={'X-Auth-Key': 'xxxx', 'Content-Type': 'application/json', 'X-Auth-User': 'xxxx', 'Accept': 'application/json', 'X-Auth-Token':'xxxx'})
            print "Response status code:", response.status_code
            print "Response content:", response.content

class MyLocust(HttpLocust):
    task_set = MyTaskSet
    min_wait = 5000
    max_wait = 15000

Thanks!

Beenz
  • 153
  • 1
  • 2
  • 7

5 Answers5

11

By adding --logfile=locustfile.log parameter when starting locust, your print messages will be redirected to a file called locustfile.log, which I think is the log you mentioned in your question.

Suppose your locust file name is locustfile.py. And you run locust on your local machine. You can start locust by locust --host=http://127.0.0.1 --logfile=locustfile.log. Then you'll be able to run locust test on http://127.0.0.1:8089/.

Brian
  • 12,145
  • 20
  • 90
  • 153
2

The --logfile option mentioned by the others is probably the easiest route. Note that you probably want to log your messages rather than printing them. I think locust sets up a special stdout logger such that print messages go to the console, but not to the log file.

An alternative to --logfile is to utilize python's logging system to add your own file appender. This is a good option if you need a rolling file appender, or have a log format that you prefer over the format that locust configures.

Here is an example of how we setup and use logging in our locust test. Notice how each instance of the taskset logs to its own logger. That makes it easy to filter the log file to a single locust. Also note that we log all HTTP errors as warnings.

from locust import HttpLocust, TaskSet, task
import itertools
import logging
import socket
from logging.handlers import RotatingFileHandler

def append_file_logger():
    root_logger = logging.getLogger()
    log_format = "%(asctime)s.%(msecs)03d000 [%(levelname)s] {0}/%(name)s : %(message)s".format(socket.gethostname())
    formatter = logging.Formatter(log_format, '%Y-%m-%d %H:%M:%S')
    file_handler = RotatingFileHandler('./locust.log', maxBytes=5 * 1024 * 1024, backupCount=3)
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)
    root_logger.addHandler(file_handler)    

append_file_logger()

counter = itertools.count()

class FooTaskSet(TaskSet):
    def on_start(self):
        self.logger = logging.getLogger('locust-%03d' % counter.next())
        self.logger.info('Hatching locust')

    @task
    def send(self):
        response = self.client.post(...)
        if not response.ok:
            self.logger.warn('Error sending post') # TODO add status code, url, and reponse to the log 

Final suggestion : If you have multiple tasks, configure them to log all http errors with the same format. Makes it easy to extract data from your log.

bigh_29
  • 2,529
  • 26
  • 22
1

In case it wasn't obvious, there isn't a default set. https://github.com/locustio/locust/blob/master/locust/main.py

line 167

# log file
parser.add_option(
    '--logfile',
    action='store',
    type='str',
    dest='logfile',
    default=None,
    help="Path to log file. If not set, log will go to stdout/stderr",
)

Just pass the preferred location in case running as a background process as lyen mentioned.

Priyeshj
  • 1,295
  • 2
  • 17
  • 32
1

Add the following piece of code to your locust file :

import logging
log = logging.getLogger()
log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh = logging.FileHandler('locust.log')
fh.setLevel(logging.DEBUG)

Now you can keep the loggers or the print statement they will be populated to your "locust.log" file.
This should do the magic for you.

Ashutosh
  • 917
  • 10
  • 19
0

You have a syntax error on the line starting with response = self.client.post(.... The last string is never closed: 'X-Auth-Token':'xxxx}.

Change it to 'X-Auth-Token':'xxxx'} and the script should work fine.

When starting Locust with the script you posted (with the syntax error), you'll get an Exception and stack trace immediately.

heyman
  • 4,845
  • 3
  • 26
  • 19
  • When I replaced the actual token with the x's, I think I took out the closing quote by accident. In my script, it's there. the errors that I see are 500's. I was wondering where the logs are for Locust so that I can take a look and see what the post looks like. When I use Postman with the same url, body and headers - it works fine. – Beenz Sep 26 '14 at 13:56
  • I see. I'm not sure what kind of log you are referring to. One way to debug the problem could be to do the request using both postman and Locust to http://requestb.in/ and then see what differs. – heyman Sep 26 '14 at 18:08