[comment]: # translation:outdated

[comment]: # aside:5

[comment]: # ({f2a0429f-ebcec779})
# Wysyłanie danych do serwera lub proxy Zabbix

[zabbix\_utils](https://github.com/zabbix/python-zabbix-utils/blob/main/README.md) umożliwia wysyłanie wartości pozycji do [pozycji trapper](/manual/config/items/itemtypes/trapper) na serwer lub proxy Zabbix (podobnie jak [Zabbix sender](/manual/concepts/sender)).

Możesz wysłać pojedynczą wartość, wiele wartości, a nawet kierować dane do wielu klastrów Zabbix.

Dane mogą być wysyłane w trybie synchronicznym lub asynchronicznym:

-   W trybie synchronicznym skrypt Python wysyła wartości i czeka na odpowiedź przed kontynuowaniem działania; jest to odpowiednie rozwiązanie dla prostych, sekwencyjnych i przewidywalnych operacji.
-   W trybie asynchronicznym skrypt wysyła wartości bez oczekiwania na każdą odpowiedź, umożliwiając równoległe wykonywanie innych operacji; jest to bardziej efektywne w przypadku wolnych żądań lub dużych partii danych.

Przykłady na tej stronie koncentrują się na trybie synchronicznym, chociaż [tryb asynchroniczny](#asynchronous-mode) opiera się na podobnych wzorcach.
Dodatkowe przykłady są dostępne w repozytorium GitHub [zabbix_utils](https://github.com/zabbix/python-zabbix-utils/tree/main/examples).

[comment]: # ({/f2a0429f-ebcec779})

[comment]: # ({33a3626c-2b58225a})
#### Import

Aby używać `zabbix_utils` do wysyłania wartości pozycji, zaimportuj klasę `Sender` w swoim skrypcie:

```python
from zabbix_utils import Sender
```

Aby wysyłać wiele wartości, możesz również zaimportować klasę `ItemValue`:

```python
from zabbix_utils import Sender, ItemValue
```

[comment]: # ({/33a3626c-2b58225a})

[comment]: # ({6215a382-248fa427})
#### Wyślij pojedynczą wartość

Aby wysłać wartość pozycji:

1. Utwórz instancję `Sender`, podając adres IP i port swojego serwera lub proxy Zabbix.
2. Wywołaj metodę `send_value()` na instancji `Sender`, używając następującego formatu:

```python
sender_instance.send_value('host', 'item.key', 'value', optional_timestamp, optional_nanoseconds)
```

Na przykład, aby wysłać `1` do pozycji trapper `service.status` na hoście `Linux server`:

```python
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send_value('Linux server', 'service.status', 1)
```

[comment]: # ({/6215a382-248fa427})

[comment]: # ({ba5ab006-8c41d6ba})
##### Używanie niestandardowego adresu IP

Jeśli serwer uruchamiający skrypt ma wiele adresów IP, możesz określić `source_ip`, którego `Sender` ma używać podczas wysyłania wartości do serwera Zabbix lub proxy:

```python
sender = Sender(
    server='127.0.0.1',
    port=10051,
    source_ip='10.10.7.1'
)
```

[comment]: # ({/ba5ab006-8c41d6ba})

[comment]: # ({bff53bf5-de824c12})
##### Używanie timeout

Możesz ustawić `timeout` odpowiedzi dla `Sender`, aby kontrolować, jak długo skrypt powinien czekać na odpowiedź z serwera Zabbix lub proxy, zanim zrezygnuje:

```python
sender = Sender(
    server='127.0.0.1',
    port=10051,
    timeout=30
)
```

[comment]: # ({/bff53bf5-de824c12})

[comment]: # ({04ae72fb-62dd1793})
##### Używanie pliku konfiguracyjnego agent

Możesz pozwolić, aby zabbix\_utils odczytywał parametry [`Server`](/manual/appendix/config/zabbix_agentd#server) lub [`ServerActive`](/manual/appendix/config/zabbix_agentd#serveractive) z lokalnego pliku konfiguracyjnego Zabbix agent lub agent 2.
W takich przypadkach nie musisz określać parametrów połączenia podczas tworzenia instancji `Sender`:

```python
sender = Sender(
    use_config=True,
    config_path='/etc/zabbix/zabbix_agent2.conf'
)
```

::: noteimportant
Jeśli `ServerActive` zawiera jeden lub więcej klastrów Zabbix z wieloma instancjami serwer, `Sender` wysyła dane do pierwszego dostępnego serwer w każdym klastrze.
Jeśli `ServerActive` nie jest ustawiony, używany jest adres z `Server` z domyślnym portem (10051).
:::

[comment]: # ({/04ae72fb-62dd1793})

[comment]: # ({f95d47a7-a8b30296})
##### Używanie szyfrowania

`Sender` nie zawiera wbudowanej obsługi szyfrowania, ale można ją zapewnić, tworząc opakowanie przy użyciu bibliotek zewnętrznych:

```python
def psk_wrapper(sock, tls):
    # ...
    # Implementacja opakowania TLS PSK dla gniazda
    # ...

sender = Sender(
    server='127.0.0.1',
    port=10051,
    socket_wrapper=psk_wrapper
)
```

[comment]: # ({/f95d47a7-a8b30296})

[comment]: # ({e0a8b11b-b6a3d94d})
##### Odpowiedź dla pojedynczej wartości

Odpowiedź zwrócona przez serwer Zabbix lub proxy jest przetwarzana przez bibliotekę i zwracana jako obiekt `TrapperResponse`:

```python
print(response)
# {"processed": 1, "failed": 0, "total": 1, "time": "0.000123", "chunk": 1}

print(response.processed)
# 1

print(response.failed)
# 0

print(response.total)
# 1
```

[comment]: # ({/e0a8b11b-b6a3d94d})

[comment]: # ({d5faab4e-9eeea215})
##### Tryb asynchroniczny

Tryb asynchroniczny pozwala skryptowi Python wysyłać wartości bez oczekiwania na odpowiedź z serwera Zabbix lub proxy.
Może to zwiększyć wydajność skryptu, gdy musi on wysłać wiele wartości albo gdy wysłanie niektórych wartości zajmuje dużo czasu.

Podczas korzystania z trybu asynchronicznego występuje kilka istotnych różnic w porównaniu z trybem synchronicznym:

-   Zaimportuj moduł `asyncio` języka Python (najpierw należy [zainstalować](/devel/python/install) wymagane zależności).
-   Zaimportuj `AsyncSender` zamiast `Sender`.
-   Napisz kod wewnątrz funkcji `async`.
-   Użyj `await` podczas wywoływania metody `send_value()`.

Na przykład, aby wysłać pojedynczą wartość w trybie asynchronicznym:

```python
# 1. Import asyncio for asynchronous mode, and AsyncSender from zabbix_utils:
import asyncio
from zabbix_utils import AsyncSender

# 2. Define the main async function where all data sending operations (must await) will be executed:
async def main():
    sender = AsyncSender(server='127.0.0.1', port=10051)
    response = await sender.send_value('Linux server', 'service.status', 1)

    # 3. Print the response returned by Zabbix server or proxy:
    print(response)

# 4. Run the async main() function using asyncio's event loop:
asyncio.run(main())
```

[comment]: # ({/d5faab4e-9eeea215})

[comment]: # ({b845706b-34e0ff6d})
#### Wysyłanie wielu wartości

Aby wysłać wiele wartości:

1. Przygotuj tablicę obiektów `ItemValue`, z których każdy używa tego samego formatu co metoda [`send_value()`](#send-single-value).
2. Utwórz instancję `Sender`, podając adres IP i port serwera lub proxy Zabbix.
3. Wywołaj metodę `send()` (zamiast `send_value()`) na instancji `Sender`, przekazując tablicę obiektów z wartościami do wysłania.

Na przykład, aby wysłać pięć wartości do różnych hostów:

```python
items = [
    ItemValue('server-de', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-fr', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-uk', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-nl', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-pl', 'service.status', 'up', 1770887205, 100),
]

sender = Sender(server='127.0.0.1', port=10051)
response = sender.send(items)
```

[comment]: # ({/b845706b-34e0ff6d})

[comment]: # ({c0410a6d-5848e96f})
##### Używanie niestandardowego rozmiaru fragmentu

Jeśli chcesz wysłać więcej wartości, niż pozycja trapper może przyjąć w pojedynczym żądaniu, możesz podzielić je na fragmenty.

Domyślnie rozmiar fragmentu wynosi 250 wartości.
Możesz go zmienić, ustawiając parametr `chunk_size` podczas tworzenia instancji `Sender`.

Na przykład, aby wysłać pięć wartości w trzech fragmentach (2-2-1), ustaw parametr `chunk_size` na `2`:

```python
items = [
    ItemValue('server-de', 'service.status', 'up'),
    ItemValue('server-fr', 'service.status', 'up'),
    ItemValue('server-uk', 'service.status', 'up'),
    ItemValue('server-nl', 'service.status', 'up'),
    ItemValue('server-pl', 'service.status', 'up'),
]

sender = Sender(server='127.0.0.1', port=10051, chunk_size=2)
response = sender.send(items)
```

[comment]: # ({/c0410a6d-5848e96f})

[comment]: # ({b06724dd-5a0b5783})
##### Wysyłanie wartości do wielu klastrów Zabbix

Aby wysyłać wartości do wielu klastrów Zabbix:

1. Przygotuj tablicę klastrów Zabbix. Jeśli klaster ma wiele węzłów, wartość zostanie wysłana do pierwszego **dostępnego** węzła każdego klastra.
2. Utwórz obiekt `Sender`, podając tablicę klastrów Zabbix.
3. Wywołaj metodę `send_value()` na instancji `Sender`, używając tego samego formatu jak w metodzie [`send_value()`](#send-single-value).

Na przykład, aby wysłać wartość do pierwszego dostępnego węzła w każdym klastrze:

```python
zabbix_clusters = [
    ['zabbix.cluster1.node1', 'zabbix.cluster1.node2:10051'],
    ['zabbix.cluster2.node1:10051', 'zabbix.cluster2.node2', 'zabbix.cluster2.node3']
]

sender = Sender(clusters=zabbix_clusters)
response = sender.send_value('Linux server', 'service.status', 1)
```

[comment]: # ({/b06724dd-5a0b5783})

[comment]: # ({2c3cc8b2-d7964287})
##### Odpowiedź dla wielu wartości

Domyślnie `Sender` zwraca zagregowany wynik wysyłania wartości dla wszystkich hostów lub klastrów:

```python
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
```

Jeśli potrzebujesz bardziej szczegółowych informacji, możesz sprawdzić wyniki dla każdego klastra i każdego fragmentu za pomocą atrybutu `response.details`:

```python
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}

if response.failed == 0:
    print(f"Wartość została wysłana pomyślnie w {response.time}")
else:
    print(response.details)
    # {
    #     127.0.0.1:10051: [
    #         {
    #             "processed": 1,
    #             "failed": 0,
    #             "total": 1,
    #             "time": "0.000051",
    #             "chunk": 1
    #         }
    #     ],
    #     zabbix.example.local:10051: [
    #         {
    #             "processed": 1,
    #             "failed": 0,
    #             "total": 1,
    #             "time": "0.000057",
    #             "chunk": 1
    #         }
    #     ]
    # }

    for node, chunks in response.details.items():
        for resp in chunks:
            print(f"Przetworzono {resp.processed} z {resp.total} na {node.address}:{node.port}")
            # Przetworzono 1 z 1 na 127.0.0.1:10051
            # Przetworzono 1 z 1 na zabbix.example.local:10051
```

[comment]: # ({/2c3cc8b2-d7964287})
