Search in sources :

Example 1 with MessageEvent

use of org.graylog2.plugin.buffers.MessageEvent in project graylog2-server by Graylog2.

the class DecodingProcessor method processMessage.

private void processMessage(final MessageEvent event) throws ExecutionException {
    final RawMessage raw = event.getRaw();
    // for backwards compatibility: the last source node should contain the input we use.
    // this means that extractors etc defined on the prior inputs are silently ignored.
    // TODO fix the above
    String inputIdOnCurrentNode;
    try {
        // .inputId checked during raw message decode!
        inputIdOnCurrentNode = Iterables.getLast(raw.getSourceNodes()).inputId;
    } catch (NoSuchElementException e) {
        inputIdOnCurrentNode = null;
    }
    final Codec.Factory<? extends Codec> factory = codecFactory.get(raw.getCodecName());
    if (factory == null) {
        LOG.warn("Couldn't find factory for codec <{}>, skipping message {} on input <{}>.", raw.getCodecName(), raw, inputIdOnCurrentNode);
        return;
    }
    final Codec codec = factory.create(raw.getCodecConfig());
    final String baseMetricName = name(codec.getClass(), inputIdOnCurrentNode);
    Message message = null;
    Collection<Message> messages = null;
    final Timer.Context decodeTimeCtx = parseTime.time();
    final long decodeTime;
    try {
        // TODO The Codec interface should be changed for 2.0 to support collections of messages so we can remove this hack.
        if (codec instanceof MultiMessageCodec) {
            messages = ((MultiMessageCodec) codec).decodeMessages(raw);
        } else {
            message = codec.decode(raw);
        }
    } catch (RuntimeException e) {
        LOG.error("Unable to decode raw message {} on input <{}>.", raw, inputIdOnCurrentNode);
        metricRegistry.meter(name(baseMetricName, "failures")).mark();
        throw e;
    } finally {
        decodeTime = decodeTimeCtx.stop();
    }
    if (message != null) {
        event.setMessage(postProcessMessage(raw, codec, inputIdOnCurrentNode, baseMetricName, message, decodeTime));
    } else if (messages != null && !messages.isEmpty()) {
        final List<Message> processedMessages = Lists.newArrayListWithCapacity(messages.size());
        for (final Message msg : messages) {
            final Message processedMessage = postProcessMessage(raw, codec, inputIdOnCurrentNode, baseMetricName, msg, decodeTime);
            if (processedMessage != null) {
                processedMessages.add(processedMessage);
            }
        }
        event.setMessages(processedMessages);
    }
}
Also used : RawMessage(org.graylog2.plugin.journal.RawMessage) Message(org.graylog2.plugin.Message) MultiMessageCodec(org.graylog2.plugin.inputs.codecs.MultiMessageCodec) MultiMessageCodec(org.graylog2.plugin.inputs.codecs.MultiMessageCodec) Codec(org.graylog2.plugin.inputs.codecs.Codec) Timer(com.codahale.metrics.Timer) List(java.util.List) RawMessage(org.graylog2.plugin.journal.RawMessage) NoSuchElementException(java.util.NoSuchElementException)

Example 2 with MessageEvent

use of org.graylog2.plugin.buffers.MessageEvent in project graylog2-server by Graylog2.

the class OutputBufferProcessor method onEvent.

/**
 * Each message will be written to one or more outputs.
 * <p>
 * The default output is always being used for every message, but optionally the message can be routed to additional
 * outputs, currently based on the stream outputs that are configured in the system.
 * </p>
 * <p>
 * The stream outputs are time limited so one bad output does not impact throughput too much. Essentially this means
 * that the work of writing to the outputs is performed, but the writer threads will not wait forever for stream
 * outputs to finish their work. <b>This might lead to increased memory usage!</b>
 * </p>
 * <p>
 * The default output, however, is allowed to block and is not subject to time limiting. This is important because it
 * can exert back pressure on the processing pipeline this way, making sure we don't run into excessive heap usage.
 * </p>
 *
 * @param event the message to write to outputs
 * @throws Exception
 */
@Override
public void onEvent(MessageEvent event) throws Exception {
    incomingMessages.mark();
    final Message msg = event.getMessage();
    if (msg == null) {
        LOG.debug("Skipping null message.");
        return;
    }
    LOG.debug("Processing message <{}> from OutputBuffer.", msg.getId());
    final Set<MessageOutput> messageOutputs = outputRouter.getStreamOutputsForMessage(msg);
    msg.recordCounter(serverStatus, "matched-outputs", messageOutputs.size());
    final Future<?> defaultOutputCompletion = processMessage(msg, defaultMessageOutput);
    final CountDownLatch streamOutputsDoneSignal = new CountDownLatch(messageOutputs.size());
    for (final MessageOutput output : messageOutputs) {
        processMessage(msg, output, streamOutputsDoneSignal);
    }
    // Wait until all writer threads for stream outputs have finished or timeout is reached.
    if (!streamOutputsDoneSignal.await(configuration.getOutputModuleTimeout(), TimeUnit.MILLISECONDS)) {
        LOG.warn("Timeout reached. Not waiting any longer for stream output writer threads to complete.");
    }
    // this exerts the back pressure to the system
    if (defaultOutputCompletion != null) {
        Uninterruptibles.getUninterruptibly(defaultOutputCompletion);
    } else {
        LOG.error("The default output future was null, this is a bug!");
    }
    if (msg.hasRecordings()) {
        LOG.debug("Message event trace: {}", msg.recordingsAsString());
    }
    outputThroughput.inc();
    LOG.debug("Wrote message <{}> to all outputs. Finished handling.", msg.getId());
    event.clearMessages();
}
Also used : MessageOutput(org.graylog2.plugin.outputs.MessageOutput) DefaultMessageOutput(org.graylog2.outputs.DefaultMessageOutput) Message(org.graylog2.plugin.Message) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 3 with MessageEvent

use of org.graylog2.plugin.buffers.MessageEvent in project graylog2-server by Graylog2.

the class ProcessBuffer method insertBlocking.

public void insertBlocking(@Nonnull RawMessage rawMessage) {
    final long sequence = ringBuffer.next();
    final MessageEvent event = ringBuffer.get(sequence);
    event.setRaw(rawMessage);
    ringBuffer.publish(sequence);
    afterInsert(1);
}
Also used : MessageEvent(org.graylog2.plugin.buffers.MessageEvent)

Aggregations

Message (org.graylog2.plugin.Message)2 Timer (com.codahale.metrics.Timer)1 List (java.util.List)1 NoSuchElementException (java.util.NoSuchElementException)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 DefaultMessageOutput (org.graylog2.outputs.DefaultMessageOutput)1 MessageEvent (org.graylog2.plugin.buffers.MessageEvent)1 Codec (org.graylog2.plugin.inputs.codecs.Codec)1 MultiMessageCodec (org.graylog2.plugin.inputs.codecs.MultiMessageCodec)1 RawMessage (org.graylog2.plugin.journal.RawMessage)1 MessageOutput (org.graylog2.plugin.outputs.MessageOutput)1