import _ from 'lodash'; import moment from 'moment'; import { LogLevel, LogsModel, LogRow } from 'app/core/logs_model'; export function getLogLevel(line: string): LogLevel { if (!line) { return undefined; } let level: LogLevel; Object.keys(LogLevel).forEach(key => { if (!level) { const regexp = new RegExp(`\\b${key}\\b`, 'i'); if (regexp.test(line)) { level = LogLevel[key]; } } }); return level; } export function getSearchMatches(line: string, search: string) { // Empty search can send re.exec() into infinite loop, exit early if (!line || !search) { return []; } const regexp = new RegExp(`(?:${search})`, 'g'); const matches = []; let match = regexp.exec(line); while (match) { matches.push({ text: match[0], start: match.index, length: match[0].length, }); match = regexp.exec(line); } return matches; } export function processEntry(entry: { line: string; timestamp: string }, stream): LogRow { const { line, timestamp } = entry; const { labels } = stream; const key = `EK${timestamp}${labels}`; const time = moment(timestamp); const timeFromNow = time.fromNow(); const timeLocal = time.format('YYYY-MM-DD HH:mm:ss'); const searchMatches = getSearchMatches(line, stream.search); const logLevel = getLogLevel(line); return { key, logLevel, searchMatches, timeFromNow, timeLocal, entry: line, timestamp: timestamp, }; } export function processStreams(streams, limit?: number): LogsModel { const combinedEntries = streams.reduce((acc, stream) => { return [...acc, ...stream.entries.map(entry => processEntry(entry, stream))]; }, []); const sortedEntries = _.chain(combinedEntries) .sortBy('timestamp') .reverse() .slice(0, limit || combinedEntries.length) .value(); return { rows: sortedEntries }; }