splunk篇5-导出csv文件中文乱码

dashboard里面有一个table,table里面的中文内容正常,但是导出成csv文件的时候,用excel打开中文乱码,用notepad代码内容正常。到这里有经验的同学应该知道问题出在哪里了,没错就是csv文件缺少了BOM头。所以用excel打开就是乱码的。

本来是一个很简单的问题,自己在写导出功能的时候也曾碰到过此类问题,只需要在字节流的最前面追加3个字节的bom字节就好了,但是这个问题是splunk里面的,问题难点是找到对应的源码修改之。

解决方案,1:导出的csv文件用notepad打开然后改编码格式问utf-8-bom
2:修改splunk的下载接口的源码,给他加上bom头
~/splunk/lib/python3.7/site-packages/splunk/appserver/mrsparkle/controllers/search.py,下面接口位置getJobAsset()->self.streamJobExport()-> ~/splunk/lib/python3.7/site-packages/splunk/rest/__init__.py.readall()
可以看到这个类返回的是一个genertor类型,添加新方法。针对csv添加新方法,

def readallCsv(self, blocksize=32768):
        """
        Returns a generator reading blocks of data from the response
        until all data has been read
        """
        response = self.response
        fileObject.write(str(type(response)))
        fileObject.flush()
        if kwargs['outputMode'] == 'csv':
            while True:
                data = response.read(blocksize)
            output = ""
            try:
                code_of_html = data.decode()
                output = "".join((codecs.BOM_UTF8.decode(), code_of_html))
                fileObject.write(str(type(data)))
                fileObject.flush()
            except Exception as e:
                break
            if not data:
                break
            yield output

此方法会加上pom头。然后修改search.py.elf.streamJobExport(),针对csv类型跳转到新方法
在streamJobExport()的  stream = rest.streamingRequest(uri, getargs=getargs, postargs=postargs, timeout=export_timeout)此行下面,添加
        if kwargs['outputMode']=='csv':
            result = stream.readallCsv()
        else:
            result=stream.readall()
        return result
至此完美解决问题,csv类型跳转到新方法,其他类型还是原来的方法。

做补充,上述代码有bug,改动后如下

  def readallCsv(self, blocksize=32768):
        fileObject = open("/opt/code/logs/search.log", 'a+')
        fileObject.write("\nreadallCsv")
        fileObject.flush()

        """
        Returns a generator reading blocks of data from the response
        until all data has been read
        """
        response = self.response
        fileObject.write(str(type(response)))
        fileObject.flush()
        while True:
            data = response.read(blocksize)
            if not data:
                break
            try:
                data = b'\xef\xbb\xbf' + data
            except Exception as e:
                fileObject.write("\nerror")
                fileObject.write("\n" + traceback.format_exc())
                fileObject.flush()
            if not data:
                break
            yield data

你可能感兴趣的:(splunk)