zenoss4 解决中文事件支持。

时间:2021-02-23 06:50:03
环境介绍:
centos6.4  
rpm包安装 zenoss4.2.4  


修改的地方:
文件 :/opt/zenoss/Products/ZenMessaging/queuemessaging/adapters.py
def _safestr(s):
    if isinstance(s, str):
        return s.decode()
    elif not isinstance(s, basestring):
        s = str(s)

    return s
原因: 放入rabbitmq之前,防止把中文跟过滤掉        
    
下载zenoss4.2.4源码
文件 DaoUtils.java
    修改 truncateStringToUtf8函数
    
    return (newLength == length) ? original : original.substring(0,
                newLength);
                
    修改成
     try {
         return (newLength == length) ? original : original.substring(0,
             newLength);
     } catch (java.lang.StringIndexOutOfBoundsException e) {
         return original;
     } 
     
     通过 mvn 重新打jar包 生成zep-core-1.2-SNAPSHOT-sources.jar
     把zep-core-1.2-SNAPSHOT-sources.jar 文件覆盖到 /opt/zenoss/webapps/zeneventserver/WEB-INF/lib/zep-core-1.2-SNAPSHOT-sources.jar
原因:如果是长中文的话,truncateStringToUtf8 这个函数在truncate的时候,会有问题。      
     
重启zenoss. 完工。     
        
    
下面是解决的过程,期间的弯路就不说了,都是血泪....

首先了解一下zenoss 事件的处理流程:


1:发送的事件,首先发送到  rabbitmq 中
2:然后一些后台进程来处理 rabbitmq 中的数据
3:最后有zeneventserver把处理之后数据,存入到 zenoss_zep中


因为涉及到多进程通过 rabbitmq 中queues来获取数据
数据的存储采用的是 google ProtoBuf 协议

google ProtoBuf 描述见下文:
http://code.google.com/p/protobuf/

通过protobuf  先序列化 事件,然后放入到queue中
在序列化的时候,对于非 unicode 有一个限制:
Defensive catchall to be sure that any string going into a protobuf can be
    decoded safely with 7-bit ASCII.  If any specialized encoding is desired, it
    is the responsibility of the caller/sender to take care of it.
    
因为zenoss 采用的是utf-8格式, 在序列化之前,进行 _safestr(s) ,会把中文的utf-8跟过滤掉
看源码:
def _safestr(s):
    if isinstance(s, str):
        try:
            unicode(s, 'ascii')
        except UnicodeDecodeError:
            s = str(s.decode('ascii','ignore'))
    elif not isinstance(s, basestring):
        s = str(s)
    return s
    
在放入 rabbitmq 之前,就把中文跟过滤掉了。  


找到源头之后 修改这个函数:
def _safestr(s):
    if isinstance(s, str):
        return s.decode()
    elif not isinstance(s, basestring):
        s = str(s)

    return s
    
重启zenoss之后,发现可以支持中文了。
美中不足的话,zenoss_zep 采用的utf-8编码,插入的是 unicode编码
不会导致丢失数据,但是通过mysql 自带的客户端 查看的时候,显示乱码。


zenoss前端在显示的时候,会有一个转换 Ext.htmlEncode ,不会影响大局。


经过测试时候,发现如果是长中文的话,zeneventserver会有问题。
查看 源码,因为对 java实在不熟悉,稍微修改一下源码,cache了异常之后,返回源字符串
插入字段过长的问题,交给mysql自动处理。
通过mvn 重新打jar, 没有搞过java,头都大了
下载 mvn  http://apache.fayea.com/apache-mirror/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.zip
配置之后,查看源码中的安装方法,重新打成 zep-core-1.2-SNAPSHOT-sources.jar,覆盖一下

重启zenoss,完成。

因为以前一直用zenoss3,解决zenoss4中文时候,期间走了不少弯路,不过对于zenoss的事件处理流程增加了了解。
不完美的地方: mysql库中存储的是 unicode ,通过myql自带工具查看时候是乱码
其实最好的解决方法不是 修改truncateStringToUtf8 这个函数。
而是在取到 unicode数据之后,转换成utf8,在用utf8插入到mysql中,对java实在不熟悉
项目时间也比较紧张,等后期在来搞他,如果有人提前解决了
告诉我我一下处理过程, 多谢。 jiaoao20080707@126.com