Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ before_install:
env:
- SPLUNK_VERSION=7.0-sdk
- SPLUNK_VERSION=7.2-sdk
- SPLUNK_VERSION=8.0-sdk

language: python

Expand Down
8 changes: 7 additions & 1 deletion splunklib/modularinput/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# under the License.

from __future__ import absolute_import
from io import TextIOBase
from splunklib.six import ensure_text

try:
import xml.etree.cElementTree as ET
except ImportError as ie:
Expand Down Expand Up @@ -104,5 +107,8 @@ def write_to(self, stream):
if self.done:
ET.SubElement(event, "done")

stream.write(ET.tostring(event))
if isinstance(stream, TextIOBase):
stream.write(ensure_text(ET.tostring(event)))
else:
stream.write(ET.tostring(event))
stream.flush()
26 changes: 17 additions & 9 deletions splunklib/modularinput/event_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from __future__ import absolute_import
import sys

from io import TextIOWrapper, TextIOBase
from splunklib.six import ensure_text
from .event import ET

try:
Expand All @@ -24,7 +26,6 @@

class EventWriter(object):
"""``EventWriter`` writes events and error messages to Splunk from a modular input.

Its two important methods are ``writeEvent``, which takes an ``Event`` object,
and ``log``, which takes a severity and an error message.
"""
Expand All @@ -42,8 +43,15 @@ def __init__(self, output = sys.stdout, error = sys.stderr):
:param output: Where to write the output; defaults to sys.stdout.
:param error: Where to write any errors; defaults to sys.stderr.
"""
self._out = output
self._err = error
if isinstance(output, TextIOBase):
self._out = output
else:
self._out = TextIOWrapper(output)

if isinstance(error, TextIOBase):
self._err = error
else:
self._err = TextIOWrapper(error)

# has the opening <stream> tag been written yet?
self.header_written = False
Expand All @@ -55,20 +63,18 @@ def write_event(self, event):
"""

if not self.header_written:
self._out.write(b"<stream>")
self._out.write(ensure_text("<stream>"))
self.header_written = True

event.write_to(self._out)

def log(self, severity, message):
"""Logs messages about the state of this modular input to Splunk.
These messages will show up in Splunk's internal logs.

:param severity: ``string``, severity of message, see severities defined as class constants.
:param message: ``string``, message to log.
"""

self._err.write(("%s %s\n" % (severity, message)).encode('utf-8'))
self._err.write(ensure_text("%s %s\n" % (severity, message)))
self._err.flush()

def write_xml_document(self, document):
Expand All @@ -77,9 +83,11 @@ def write_xml_document(self, document):

:param document: An ``ElementTree`` object.
"""
self._out.write(ET.tostring(document))
data = ET.tostring(document)
self._out.write(ensure_text(data))
self._out.flush()

def close(self):
"""Write the closing </stream> tag to make this XML well formed."""
self._out.write(b"</stream>")
self._out.write(ensure_text("</stream>"))
self._out.flush()
Loading