org.ngrinder.operation.cotroller.LogMonitorController.java Source code

Java tutorial

Introduction

Here is the source code for org.ngrinder.operation.cotroller.LogMonitorController.java

Source

/* 
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */
package org.ngrinder.operation.cotroller;

import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;
import org.ngrinder.common.controller.BaseController;
import org.springframework.http.HttpEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;

import static org.ngrinder.common.util.CollectionUtils.buildMap;

/**
 * Log monitor controller.
 *
 * This class runs with {@link Tailer} implementation. Whenever the underlying log file is changed. this class gets the
 * changes. and keep them(max 10000 byte) in the memory. Whenever user requests the log, it returns latest changes with
 * the index of the log.
 *
 * This is only available in the non-clustered instance.
 *
 * @author JunHo Yoon
 */
@Controller
@RequestMapping("/operation/log")
@PreAuthorize("hasAnyRole('A')")
public class LogMonitorController extends BaseController {

    private static final int LOGGER_BUFFER_SIZE = 10000;

    /**
     * Buffer to store the latest log.
     */
    private volatile StringBuffer stringBuffer = new StringBuffer(LOGGER_BUFFER_SIZE);

    private Tailer tailer;

    private long count = 0;
    private long modification = 0;

    /**
     * Initialize.
     */
    @PostConstruct
    public void init() {
        if (!isClustered()) {
            initTailer();
        }
    }

    /**
     * Initialize the {@link Tailer}.
     */
    private synchronized void initTailer() {
        File logFile = getLogFile();
        if (tailer != null) {
            tailer.stop();
        }
        tailer = Tailer.create(logFile, new TailerListenerAdapter() {
            /**
             * Handles a line from a Tailer.
             *
             * @param line
             *            the line.
             */
            public void handle(String line) {
                synchronized (this) {
                    if (stringBuffer.length() + line.length() > 5000) {
                        count++;
                        modification = 0;
                        stringBuffer = new StringBuffer();
                    }
                    modification++;
                    if (stringBuffer.length() > 0) {
                        stringBuffer.append("<br>");
                    }
                    stringBuffer.append(line.replace("\n", "<br>"));
                }
            }
        }, 1000, true);
    }

    /**
     * Get the log file.
     *
     * @return log file
     */
    File getLogFile() {
        String logFileName = "ngrinder.log";
        return new File(getConfig().getHome().getGlobalLogFile(), logFileName);
    }

    /**
     * Finalize bean.
     */
    @PreDestroy
    public void destroy() {
        if (!isClustered()) {
            tailer.stop();
        }
    }

    /**
     * Return the logger first page.
     *
     * @param model model
     * @return operation/logger
     */
    @RequestMapping("")
    public String getOne(Model model) {
        model.addAttribute("verbose", getConfig().isVerbose());
        return "operation/logger";
    }

    /**
     * Get the last log in the form of json.
     *
     * @return log json
     */
    @RequestMapping("/last")
    public HttpEntity<String> getLast() {
        return toJsonHttpEntity(buildMap("index", count, "modification", modification, "log", stringBuffer));
    }

    /**
     * Turn on verbose log mode.
     *
     * @param verbose true if verbose mode
     * @return success message if successful
     */
    @RequestMapping("/verbose")
    public HttpEntity<String> enableVerbose(
            @RequestParam(value = "verbose", defaultValue = "false") Boolean verbose) {
        getConfig().initLogger(verbose);
        initTailer();
        return toJsonHttpEntity(buildMap("success", true));
    }

}