Доброе время суток. На мой взгляд результат получаю правильный, но валидатор не принимает. Нужно ли в данном задании рассматривать ситуацию, когда в логе некорректные/неполные данные и надо отрабатывать их исключениями?

Буду благодарен за совет или за набор тестовых запросов.

Условие : Задание 1

Сегодня мы напишем парсер логов. Лог файл имеет следующий формат: ip username date event status Где: ip - ip адрес с которого пользователь произвел событие. user - имя пользователя (одно или несколько слов разделенные пробелами). date - дата события в формате day.month.year hour:minute:second event - одно из событий: LOGIN - пользователь залогинился, DOWNLOAD_PLUGIN - пользователь скачал плагин, WRITE_MESSAGE - пользователь отправил сообщение, SOLVE_TASK - пользователь попытался решить задачу, DONE_TASK - пользователь решил задачу. Для событий SOLVE_TASK и DONE_TASK существует дополнительный параметр, который указывается через пробел, это номер задачи. status - статус: OK - событие выполнилось успешно, FAILED - событие не выполнилось, ERROR - произошла ошибка.

Пример строки из лог файла: "146.34.15.5 Eduard Petrovich Morozko 05.01.2021 20:22:55 DONE_TASK 48 FAILED". Записи внутри лог файла не обязательно упорядочены по дате, события могли произойти и быть записаны в лог в разной последовательности.

Класс, который будет отвечать за парсинг логов называется LogParser. 1.1. Добавь в класс LogParser конструктор с парметром Path logDir, где logDir - директория с логами (логов может быть несколько, все они должны иметь расширение log). 1.2. Реализуй интерфейс IPQuery у класса LogParser: 1.2.1. Метод getNumberOfUniqueIPs(Date after, Date before) должен возвращать количество уникальных IP адресов за выбранный период. Здесь и далее, если в методе есть параметры Date after и Date before, то нужно возвратить данные касающиеся только данного периода (включая даты after и before). Если параметр after равен null, то нужно обработать все записи, у которых дата меньше или равна before. Если параметр before равен null, то нужно обработать все записи, у которых дата больше или равна after. Если и after, и before равны null, то нужно обработать абсолютно все записи (без фильтрации по дате). 1.2.2. Метод getUniqueIPs() должен возвращать множество, содержащее все неповторяющиеся IP. Тип в котором будем хранить IP будет String. 1.2.3. Метод getIPsForUser() должен возвращать IP, с которых работал переданный пользователь. 1.2.4. Метод getIPsForEvent() должен возвращать IP, с которых было произведено переданное событие. 1.2.5. Метод getIPsForStatus() должен возвращать IP, события с которых закончилось переданным статусом.

Реализацию метода main() можешь менять по своему усмотрению.

Реализация парсера:

package com.javarush.test.level39.lesson09.big01;

import com.javarush.test.level39.lesson09.big01.query.IPQuery;

import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern;

public class LogParser implements IPQuery { private Path logDir;

public LogParser(Path logDir)
{
    this.logDir = logDir;
}

private List<LogItem> getLog(Date after, Date before){
    List<LogItem> logItems = getLog();

    if (after == null && before == null) return logItems;

    for (int i = logItems.size() - 1; i >= 0; i--){
        if ((after != null && !logItems.get(i).date.after(after))
                || (before != null && !logItems.get(i).date.before(before))){
            logItems.remove(i);
        }
    }

    return logItems;
}

private List<LogItem> getLog()
{
    List<LogItem> log = new ArrayList<>();
    if (logDir == null || !Files.isDirectory(logDir) || Files.notExists(logDir))
        return null;

    try (DirectoryStream<Path> stream = Files.newDirectoryStream(logDir, "*.log"))
    {
        for (Path logFile : stream)
        {
            try (BufferedReader reader = new BufferedReader(new FileReader(logFile.toFile())))
            {
                String record = reader.readLine();
                while (record != null)
                {
                    log.add(getItem(record));
                    record = reader.readLine();
                }
            }
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    return log;
}

@Override
public int getNumberOfUniqueIPs(Date after, Date before)
{
    Set<String> ipSet = getUniqueIPs(after, before);
    return ipSet.size();
}

@Override
public Set<String> getUniqueIPs(Date after, Date before)
{
    Set<String> ipSet = new HashSet<>();
    List<LogItem> logItems = getLog(after, before);
    for (LogItem item : logItems){
        ipSet.add(item.ip);
    }
    return ipSet;
}

@Override
public Set<String> getIPsForUser(String user, Date after, Date before)
{
    if (user == null) return null;

    Set<String> ipSet = new HashSet<>();
    List<LogItem> logItems = getLog(after, before);
    for (LogItem item : logItems){
        if (user.equals(item.name))
        {
            ipSet.add(item.ip);
        }
    }
    return ipSet;
}

@Override
public Set<String> getIPsForEvent(Event event, Date after, Date before)
{
    if (event == null) return null;

    Set<String> ipSet = new HashSet<>();
    List<LogItem> logItems = getLog(after, before);
    for (LogItem item : logItems){
        if (event == item.event)
        {
            ipSet.add(item.ip);
        }
    }
    return ipSet;
}

@Override
public Set<String> getIPsForStatus(Status status, Date after, Date before)
{
    if (status == null) return null;

    Set<String> ipSet = new HashSet<>();
    List<LogItem> logItems = getLog(after, before);
    for (LogItem item : logItems){
        if (status == item.status)
        {
            ipSet.add(item.ip);
        }
    }
    return ipSet;
}

private class LogItem
{
    String ip;
    String name;
    Date date;
    Event event;
    int taskId;
    Status status;

    @Override
    public String toString()
    {
        return "LogItem{" +
                "ip='" + ip + '\'' +
                ", name='" + name + '\'' +
                ", date=" + new SimpleDateFormat("dd.MM.yyyy").format(date) +
                ", event=" + event +
                ", taskId=" + taskId +
                ", status=" + status +
                '}';
    }
}

private LogItem getItem(String logRecord)
{
    LogItem item = new LogItem();
    StringBuilder builder = new StringBuilder(logRecord);
    Pattern pattern = Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
    Matcher matcher = pattern.matcher(builder.toString());
    if (matcher.find())
    {
        item.ip = builder.substring(matcher.start(), matcher.end());
        builder.delete(matcher.start(), matcher.end());
    }

    DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
    pattern = Pattern.compile("\\d{2}\\.\\d{2}\\.\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}");
    matcher = pattern.matcher(builder.toString());

    if (matcher.find())
    {
        try
        {
            item.date = format.parse(matcher.group());

        }
        catch (Exception e)
        {
        }
        item.name = builder.substring(0, matcher.start()).trim();
        builder.delete(0, matcher.end());
    }

    pattern = Pattern.compile("(LOGIN)|(DOWNLOAD_PLUGIN)|(WRITE_MESSAGE)|(SOLVE_TASK)|(DONE_TASK)");
    matcher = pattern.matcher(builder.toString());

    if (matcher.find())
    {
        item.event = Event.valueOf(matcher.group());
        builder.delete(0, matcher.end());
    }

    if (item.event == Event.DONE_TASK || item.event == Event.SOLVE_TASK)
    {
        pattern = Pattern.compile("[0-9]+");
        matcher = pattern.matcher(builder.toString());

        if (matcher.find())
        {
            item.taskId = Integer.parseInt(matcher.group());
            builder.delete(0, matcher.end());
        }
    }

    pattern = Pattern.compile("(OK)|(FAILED)|(ERROR)}");
    matcher = pattern.matcher(builder.toString());

    if (matcher.find())
    {
        item.status = Status.valueOf(matcher.group());
    }

    return item;
}

}

задан 28 Окт '16, 14:00

%D0%94%D0%BC%D0%B8%D1%82%D1%80%D0%B8%D0%B9%20%D0%A1%D0%B0%D0%B3%D0%B0%D0%B9's gravatar image

Дмитрий Сагай
153
одобрено: 0%

закрыто 13 Сен, 14:34

AndyRad's gravatar image

AndyRad
13.1k29

Вопрос был закрыт по следующей причине: "Problem is not reproducible or outdated" AndyRad 13 Сен, 14:34

Следить за вопросом

По Email:

После авторизации вы сможете подписаться на любые обновления здесь

Основы Markdown

  • *italic* or _italic_
  • **bold** or __bold__
  • ссылка:[текст](http://url.com/ "заголовок")
  • изображение?![alt текст](/path/img.jpg "заголовок")
  • нумерованный список: 1. Foo 2. Bar
  • Для того чтобы добавить разрыв строки просто добавьте два пробела.
  • основные HTML тэги, также поддерживаются

Тэги:

×3,805

Задан: 28 Окт '16, 14:00

Просмотров: 205 раз

Отредактирован: 13 Сен, 14:34