首页 > 解决方案 > 无法解决错误 - 仅将 str(不是“字节”)连接到 str

问题描述

如何解决only concatenate str (not \"bytes\") to str?我在任何地方都看不到任何 concat 的错误。我正在尝试在 AWS 中将其作为 lambda 函数运行,但出现此错误。

我看过其他类似的帖子,但我不明白问题出在我的代码中。

我也不确定它指的是哪条线。

知道如何解决这个问题吗?

{
  "errorMessage": "can only concatenate str (not \"bytes\") to str",
  "errorType": "TypeError",
  "stackTrace": [
    "  File \"/var/task/AlertMetricSender.py\", line 5, in lambda_handler\n    sender.send()\n",
    "  File \"/var/task/modules/ZabbixSender.py\", line 91, in send\n    self.__active_checks()\n",
    "  File \"/var/task/modules/ZabbixSender.py\", line 79, in __active_checks\n    response = self.__request(request)\n",
    "  File \"/var/task/modules/ZabbixSender.py\", line 66, in __request\n    response += data\n"
  ]
}

ZabbixSender.py:

#
# For sending metric value to zabbix server.
#
# You must create item as "zabbix trapper" on server.
# Because the server must be connected to agent:10050, if it is selected "zabbix agent".
#
# Usage:
#    from modules.ZabbixSender import ZabbixSender
#    ZABBIX_HOST = "zabbix.example.com"
#    ZABBIX_PORT = 10051
#    sender = ZabbixSender(ZABBIX_HOST, ZABBIX_PORT)
#    sender.add("example-hostname-01", "healthcheck", 1)
#    sender.add("example-hostname-01", "item.keyname", 0.123)
#    sender.add("example-hostname-02", "item.keyname", 1234)
#    sender.send()
#

import socket
import struct
import time
import json

class ZabbixSender:

    log = True

    def __init__(self, host='127.0.0.1', port=10051):
        self.address = (host, port)
        self.data    = []

    def __log(self, log):
        if self.log: print(log)

    def __connect(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.sock.connect(self.address)
        except:
            raise Exception("Can't connect server.")

    def __close(self):
        self.sock.close()

    def __pack(self, request):
       string = json.dumps(request).encode('utf-8')
       header = b'ZBXD' + struct.pack('<BQ', 1, len(string))
       return header + string

    def __unpack(self, response):
        header, version, length = struct.unpack('<4sBQ', response[:13])
        (data, ) = struct.unpack('<%ds'%length, response[13:13+length])
        return json.loads(data)

    def __request(self, request):
        self.__connect()
        try:
            self.sock.sendall(self.__pack(request))
        except Exception as e:
            raise Exception("Failed sending data.\nERROR: %s" % e)

        response = ''
        while True:
            data = self.sock.recv(4096)
            if not data:
                break
            response += data

        self.__close()
        return self.__unpack(response)

    def __active_checks(self):
        hosts = set()
        for d in self.data:
            hosts.add(d['host'])

        for h in hosts:
            request = {"request":"active checks", "host":h}
            self.__log("[active check] %s" % h)
            response = self.__request(request)
            if not response['response'] == 'success': self.__log("[host not found] %s" % h)

    def add(self, host, key, value, clock=None):
        if clock is None: clock = int(time.time())
        self.data.append({"host":host, "key":key, "value":value, "clock":clock})

    def send(self):
        if not self.data:
            self.__log("Not found sender data, end without sending.")
            return False

        self.__active_checks()
        request  = {"request":"sender data", "data":self.data}
        response = self.__request(request)
        result   = response['response'] == 'success'

        if result:
            for d in self.data:
                self.__log("[send data] %s" % d)
            self.__log("[send result] %s" % response['info'])
        else:
            raise Exception("Failed send data.")

        return result

if __name__ == '__main__':
    sender = ZabbixSender()
    sender.add("gedowfather-example-01", "healthcheck", 1)
    sender.add("gedowfather-example-01", "gedow.item", 1111)
    sender.send()

AlertMetricSender.py:

from modules.ZabbixSender import ZabbixSender
def lambda_handler(event, context):
    sender = ZabbixSender("10.10.10.10", 10051)
    sender.add("Zabbix server", "lambda.test", 5)
    sender.send()

更新:

如果我尝试response += data.decode(),则会收到以下错误:

{
  "errorMessage": "a bytes-like object is required, not 'str'",
  "errorType": "TypeError",
  "stackTrace": [
    "  File \"/var/task/AlertMetricSender.py\", line 5, in lambda_handler\n    sender.send()\n",
    "  File \"/var/task/modules/ZabbixSender.py\", line 91, in send\n    self.__active_checks()\n",
    "  File \"/var/task/modules/ZabbixSender.py\", line 79, in __active_checks\n    response = self.__request(request)\n",
    "  File \"/var/task/modules/ZabbixSender.py\", line 69, in __request\n    return self.__unpack(response)\n",
    "  File \"/var/task/modules/ZabbixSender.py\", line 50, in __unpack\n    header, version, length = struct.unpack('<4sBQ', response[:13])\n"
  ]
}

标签: pythonpython-3.8

解决方案


在你的__request方法上:

response = ''

应该:

response = b''

推荐阅读