Pull to refresh
130.5
X5 Tech
Всё о технологиях в ритейле

Как инженер-геодезист настраивал автоматизацию для перезапуска службы ArcGIS Server и что из этого вышло

Reading time16 min
Views1.3K

Сотрудники поддержки должны уметь программировать. Поэтому, когда на работе нам потребовалось настроить автоматизацию для перезапуска службы ArcGIS Server, а получить техническую поддержку вендора ESRI на территории РФ уже было невозможно, я решил реализовать решение самостоятельно. В статье описываю, какой путь я прошёл по поиску решения на основе советов с gis.stackexchange.com и AI.

Дисклеймер: в прошлом  я инженер-геодезист, начавший свой путь в ИТ, перейдя на работу во вторую линию поддержки системы ГИС Х5 в подразделение X5 Tech. Поэтому прошу понять и простить мне флёр джуна-программиста в данной статье.

ГИС Х5 — это один из наших инструментов развития торговых сетей X5 Group (“Пятёрочек”, “Перекрёстков” и “Чижиков”). Если совсем просто и коротко, то с помощью него мы оцениваем эффективность локации будущих магазинов по ряду параметров, на основании чего принимаем решение об их открытии в той или иной точке.

Термины и определения

ArcGIS — комплекс геоинформационных программных продуктов американской компании ESRI. Применяется для земельных кадастров, в задачах землеустройства, учёта объектов недвижимости, систем инженерных коммуникаций, геодезии и недропользования и других областях.

ArcGIS Server – это основной сервер геоинформационной системы (ГИС), созданный компанией Esri. ArcGIS Server используется для создания и управления ГИС Web-сервисами, приложениями и данными. ArcGIS Server обычно развёртывается локально в рамках сервис-ориентированной архитектуры (SOA) организации или вне её в среде облачных вычислений. 

ArcSOC (Arcgis Server Object Container) – Для обработки запроса к сервису назначенный ArcGIS Server компьютер (или сервер) использует экземпляр серверного процесса Esri ArcSOC. Каждому экземпляру соответствует свой ArcSOC.exe (исключение – сервис геообработки, для него минимальное значение  ArcSOC.exe - 2). Пользователь, формируя запрос к конкретному сервису, общается с ArcGis Server именно через ArcSOC.exe.

Суть проблемы

Настал момент, когда для быстрой ликвидации инцидента в системе потребовался автоматический перезапуск как самой службы ArcGIS Server, так и внутренних сервисов, опубликованных внутри самой службы по отдельности, либо группами.

Среди продуктов семейства ArcGIS есть ArcGIS Monitor. Это дашборд, отслеживающий ряд параметров состояния ArcGIS Server. Однако среди его функций нет возможности перезапустить ArcGIS Server в автономном режиме. Также в ходе тестов на продуктивном сервере было выявлено, что ArcGIS Monitor совместно с MongoDB откусывает приличный кусок ресурсов себе для работы. Тем самым роняя стабильность работы сервера. Ну и напоследок: ввиду санкций у меня нет доступа к лицензии ArcGIS Monitor. Остаётся вспомнить про импортозамещение и реализовать нужную утилиту самостоятельно.

Тут стоит отметить дополнительно, что с большей вероятностью проблем в работе ГИС-сервера можно избежать, если разместить ArcGIS Monitor на отдельном контуре. Но идея эта выглядит сомнительной с точки зрения затрат на серверное оборудование и ОС для программы, которая только следит, логирует и кидает вам на почту алерты.

Часть 1. Начало поиска решения

Путём простого гугления я нашёл несколько страниц:

  1. Starting and stopping ArcGIS Server map services using Python? - Geographic Information Systems Stack Exchange 

  2. https://copyprogramming.com/howto/starting-and-stopping-arcgis-server-map-services-using-python

  3. ogr2ogr / GDAL remove features in FileGDB while in use by ArcGIS Server map service - Geographic Information Systems Stack Exchange 

Вся информация достаточно старая, более чем 10-летней давности. Но это и не так страшно, т. к. сам ArcGIS Server примерно из тех же времён.

Самым популярным и часто упоминаемым решением выглядит утилита, написанная сотрудником ESRI Boston на .NET: AGSSOM.exe

Обращаться к утилите я планировал при помощи Python, как это предлагали по ссылкам выше, на gis.stackexchange. Сам запрос на Python к AGSSOM.exe:

Пример тут:
import os, subprocess
#Get list of currently running map services
stream = os.popen('D:\\GIS\\Admin\\AGSSOMv10.0\\AGSSOM.exe -list')
mapservices = stream.readlines()
lstStarted = []
for item in mapservices:
    itemSplit = item.split(',')
    if len(itemSplit) > 1:
        if itemSplit[1].find("Started.") > -1:
            lstStarted.append(itemSplit[0])
#Shutdown all map services
subprocess.call(['D:\\GIS\\Admin\\AGSSOMv10.0\\AGSSOM.exe', '-x', '*all*'])
##...Perform geodatabase tasks here
#Restart previously running map services
for mapservice in lstStarted:
    subprocess.call(['D:\\GIS\\Admin\\AGSSOMv10.0\\AGSSOM.exe', '-s', mapservice])

Нахожу репозиторий утилиты: GitHub - sam-berg/AGSSOM: AGSSOM.exe is a sample command line utility for starting, stopping, and restarting ArcGIS Server services,…который не обновлялся 9 лет….:

Код из Program.cs приводить тут не буду, слишком длинный пост.

Готового .exe-файла нет, нужно собирать проект и решение.

Ставлю Visual Studio:

Пробую собрать проект консольного приложения на Net Framework 4.8:

Добавляю зависимости в проект:

System.Runtime.Serialization.Json

System.Text.Json

Компилятор больше не ругается на ошибки, собираю проект:

Запускаю скрипт. Для начала, чтобы увидеть лист сервисов ArcGIS. И результат удручает…:

Возвращается пустой список. Скорее всего, проблемы в самом AGSSOM, но так как я ограничен во времени, у меня нет возможности полностью погрузиться в код и приводить решение в рабочее состояние.

Часть 2. Едем дальше

Нахожу информацию о том, что при помощи библиотеки Arcgis для Python можно получать (при наличии прав доступа уровня администратор)  доступ к сервисами ArcGIS, отслеживать их состояние и выполнять перезапуск при необходимости.

Сразу появились несколько вопросов:

  1. Как передавать при автономном запуске утилиты логин и пароль администратора?

  2. Как установить на сервере нужные мне библиотеки Python? Имея ограничения по безопасности и ряд проблем, решать которые у меня также времени нет.

Начнём с передачи логина и пароля, а точнее – с безопасности.

Есть логин и пароль администратора ArcGIS Server, которые нужно подавать серверу, чтобы получить доступ к внутренним сервисам ArcGIS.

Работая ранее с RPA в Х5 (Robotic Process Automation), я слышал от коллег о хранении учётных данных в Credential.

Иду искать и нахожу статью: Как не продолбать пароли в Python скриптах.

Моё почтение автору: кратко, ёмко и чётко погрузил в тему.

Итак, привет Windows Credential Locker.

Пытаясь сэкономить время, пишу запрос к ChatGPT и получаю ответ:

Пример тут:
Install-Module -Name CredentialManager
# Импортируем модуль
Import-Module -Name CredentialManager
# Создаем новые учетные данные
$credential = New-Object System.Management.Automation.PSCredential -ArgumentList "Username", ("Password" | ConvertTo-SecureString -AsPlainText -Force)
# Сохраняем учетные данные в Credential Manager
New-StoredCredential -Target "TargetName" -Credential $credential -Persist LocalMachine

Выполняю рекомендации, запускаю и получаю ответ, что у меня недостаточно прав для выполнения предложенных запросов в Powershell.

Тут следует отметить, что ещё на заре знакомства с компьютерами у меня сразу не сложилось с PowerShell. Понимаю, что для человека “посвященного” нет ничего страшного в подобных ошибках. Но для новичка, который пришёл выполнить задачу, не связанную напрямую с PowerShell, синтаксис, сообщения об ошибках и всевозможные ограничения, навешанные организацией на рабочий компьютер, превращают PowerShell в филиал местного ада с персональными пытками ментального характера.

Погружаюсь, как уже привык за годы работы в поддержке, в проблему и пытаюсь решить её. Не хватает знаний на экваторе решения? Начинаю погружение в PowerShell, Windows Credential, Active Directory…и не замечаю, как между ежедневными рабочими обязанностями консультанта поддержки и попытками решить проблему с добавлением тестового пользователя при помощи PowerShell прошло уже чуть более трёх дней…Стоп! Я определённо “думаю” не в ту сторону.

Смотрю на проблему под другим углом

Привет, Windows Prompt (CMD, консоль), которую Microsoft активно пытается заменить на PowerShell, но получается это, по моему скромному мнению, пока не очень (особенно с учётом возможности запуска в Powershell cmd.exe).

Гуглю и нахожу информацию о cdmkey.

Добавление нового пользователя происходит в формате:

cmdkey /add:<имя записи> /user:<логин> /pass:<пароль>

И, о чудо, это работает без проблем:

Проверяю Credential Manager:

Пробую получить учётные данные скриптом.

Иду в ChatGPT:
import getpass
import win32crypt

username = getpass.getuser()
path = r"C:\\Users\\{}\\AppData\\Roaming\\Microsoft\\Credentials\\".format(username)
if sys.platform.startswith("win"):
    path = path + "/"

try:
    with open(path, "r") as f:
        content = f.read().splitlines()
        for line in content:
            if line.startswith("username="):
                username = line.replace("username=", "").strip()
            elif line.startswith("password="):
                password = win32crypt.CryptUnprotectData(bytes.fromhex(line.replace("password=", "").strip()), None)
                print(f"{username}:{password}")
except FileNotFoundError:
    print("No credentials found for this user.")

Странный вариант, куда-то пропал import sys в начале…

Результат приведения к рабочему состоянию и запуск под админскими правами:

Пробую альтернативный вариант:
import os

# Получение пути к файлу Credential Manager
credentials_path = r'C:\\Users\\Default\\AppData\\Roaming\\Microsoft\\Credentials'

# Получение списка всех пользователей в файле Credential Manager
credentials = []
with open(credentials_path, 'r') as f:
    for line in f:
        data = json.loads(line)
        if 'username' in data and 'password' in data:
            credentials.append(data)

# Получение логина и пароля определенного пользователя
username = input("Введите имя пользователя: ")
for user in credentials:
    if user['username'] == username:
        print("Логин:", user['username'])
        print("Пароль:", user['password'])
        break
else:
    print("Пользователь не найден")

Результат:

Опытным путём я выяснил, что настроенных у меня привилегий администратора недостаточно…

Поиск альтернативных решений

Нахожу упоминания про библиотеку keyring для Python.

Следуя простым советам доброго человека с YouTube, при помощи Windows Prompt устанавливаю keyring и создаю тестового пользователя:

pip install keyring

Добавляю тестового пользователя:

Результат отличный: пользователь создан, данные по запросу возвращаются.

С сохранением данных для авторизации разобрался, теперь к установке нужных библиотек на сервере.

pip download arcgis -d <путь куда сложить whl>

Получаю папку со 139-ю .whl-файлами для автономной установки.

26 октября 2023 года у меня получилось без проблем выкачать .whl. На момент 5 ноября 2023 года попытка загрузить .whl падала в ошибку.

Проблема, как всегда, оказалась в пользователе. Во время написания статьи я тестировал код, запускаемый ранее. Но упустил один момент – я запускал pip download на python 3.12. Как показала практика на 5-е ноября, pip download arcgis -d <путь куда сложить файлы> не работает для библиотеки arcgis. С python 3.11 проблем не было. Будьте внимательны.

Формирую .txt файл для быстрой установки:

Пример кода тут:
import os
from os.path import isfile, join

path = r"C:\\PythonLibs\\Whl\\ArcGis"
filename = r"C:\\PythonLibs\\Whl\\ArcGis\\output.txt"

# Создаем файл для записи
with open(filename, "w") as f:
    # Проходимся по всем файлам и папкам в указанной директории
    for dirpath, dirnames, filenames in os.walk(path):
        # Отфильтровываем пустые строки и скрытые файлы
        non_hidden_files = [f for f in filenames if not f.startswith('.')]
        # Добавляем пути к файлам в файл
        for file_name in non_hidden_files:
            file_path = join(dirpath, file_name)
            f.write(file_path + "\\n")

Т. к. установку я делал по итогу на сервере с другими путями, после переноса папки с исходниками библиотек, output.txt отредактировал в Notepad++.

Примерно 3 минуты, чтобы понять, как мне переключиться на другой диск в командной строке и запускаю установку на сервере:

Новые вызовы: при установке столкнулся с ошибкой “ERROR: THESE PACKAGE DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE”.

По итогу проблему получилось решить запуском установки из локального репозитория организации. По понятным причинам процесс установки показывать тут не буду. 

Следуя документации по Arcgis API for Python, собираю скрипт для получения списка сервисов:

Пример кода тут:
from arcgis.gis import GIS
import keyring

arcgis_admin = keyring.get_credential(service_name='ArcGISAdmin')
username = arcgis_admin.username
password = arcgis_admin.password

gis = GIS("server_url", username, password, verify_cert=False)
gis_servers = gis.admin.servers.list()
print(gis_servers)

Результат:

Во время попыток достучаться до сервера различными вариациями скриптов по советам из интернета и приложенным семплам из документации Arcgis API for Python я испытал весь непередаваемый спектр эмоций, которые может испытывать человек из раза в раз терпящий неудачу в своём деле…

Выдохнули…пробуем дальше

В самом конце страницы Starting and stopping ArcGIS Server map services using Python? - Geographic Information Systems Stack Exchange – совет, набравший всего два лайка, ведёт на страницу утилиты, написанной для версии Arcgis 10.1 на python 2.7 (ArcGIS Server Administration Toolkit - 10.1+ - Обзор).

Первый подход, запуск на Python 2.7 также не дал результатов:

Поиск по форуму esri дал новую пищу для размышлений: утилита, написанная для версии arcgis 10.1 перестала быть работоспособной уже с версии arcgis 10.6. Раз так, я решил попробовать переписать утилиту для arcgis 10.8 и заодно на Python 3.

К этому моменту  появилось чёткое ощущение, что я уже мало понимаю, куда заведёт меня это путешествие в мир разработки на Python с использованием советов и AI. Исподволь подкрадывалась мысль, что нужно оставить эту идею и погружаться в проблему глобально. Начиная с изучения основ работы с url и https на Python и заканчивая материалами по написанию запросов через REST API. 

Как показало будущее: нет, мысль была неправильная.

ChatGPT

По одной из многочисленных ссылок, сохранённых в папке по решаемой задаче, я нашёл вариант получения списка ArcGIS сервисов скриптом, написанном на Python 2.7 для Arcgis Server 10.8. Отступы и переходы строк оставил “как есть” из варианта, взятого в документации. Знаю, что это выглядит ужасно (поэтому также под спойлером).

Код тут:
import json, urllib2
server = "<server>"
port = "80"
baseUrl = "http://{}:{}/arcgis/rest/services".format(server, port)
def getCatalog():
  catalog = json.load(urllib2.urlopen(baseUrl + "/" + "?f=json"))  print 'ROOT'   if "error" in catalog: return  services = catalog['services']  for service in services:
    response = json.load(urllib2.urlopen(baseUrl + '/' + service['name'] + '/' + service['type'] + "?f=json"))    print '  %s %s (%s)' % (service['name'], service['type'], 'ERROR' if "error" in response else 'SUCCESS')  folders = catalog['folders']  for folderName in folders:
    catalog = json.load(urllib2.urlopen(baseUrl + "/" + folderName + "?f=json"))    print folderName    if "error" in catalog: return    services = catalog['services']    for service in services:
      response = json.load(urllib2.urlopen(baseUrl + '/' + service['name'] + '/' + service['type'] + "?f=json"))      print '  %s %s (%s)' % (service['name'], service['type'], 'ERROR' if "error" in response else 'SUCCESS')
getCatalog()

Прошу у ChatGPT переписать этот скрипт c Python 2 на Python 3 и обращение к серверу по протоколу https, вместо http.

Ответ ChatGPT:
import json
import urllib.request

server = "<server>"
port = "80"
baseUrl = "https://{}:{}/arcgis/rest/services".format(server, port)

def getCatalog():
    with urllib.request.urlopen(baseUrl + "/" + "?f=json") as url:
        catalog = json.loads(url.read().decode())
    print('ROOT')
    if "error" in catalog: 
        return
    services = catalog['services']
    for service in services:
        with urllib.request.urlopen(baseUrl + '/' + service['name'] + '/' + service['type'] + "?f=json") as url:
            response = json.loads(url.read().decode())
        print('  %s %s (%s)' % (service['name'], service['type'], 'ERROR' if "error" in response else 'SUCCESS'))
    folders = catalog['folders']
    for folderName in folders:
        with urllib.request.urlopen(baseUrl + "/" + folderName + "?f=json") as url:
            catalog = json.loads(url.read().decode())
        print(folderName)
        if "error" in catalog: 
            return
        services = catalog['services']
        for service in services:
            with urllib.request.urlopen(baseUrl + '/' + service['name'] + '/' + service['type'] + "?f=json") as url:
                response = json.loads(url.read().decode())
            print('  %s %s (%s)' % (service['name'], service['type'], 'ERROR' if "error" in response else 'SUCCESS'))

getCatalog()

Корректирую одну строку под мой вариант адреса: Корректирую одну строку под мой вариант адреса: Корректирую одну строку под мой вариант адреса: Корректирую одну строку под мой вариант адреса: Корректирую одну строку под мой вариант адреса:

Корректирую одну строку под мой вариант адреса:

baseUrl = "https://{}/arcgis/rest/services".format(server)

И запускаю… 

Успех! Ответ вернул список сервисов:

Закрыв рабочие задачи, я выделил рабочий день на то, чтобы собрать рабочую версию скрипта, который для начала хотя бы сможет отображать состояние сервисов.

В начале работа с ChatGPT приносила сплошное удовольствие – правильно написанные промпты находили понимание у машины и она отвечала ладно написанными скриптами. Но чем более подробно я описывал требуемое, тем качественно хуже становились мои промпты. И, как результат, скрипты на выходе не могли уже полностью соответствовать мысли, заключённой в промпте. Вот она – разница между тем, как ты разбираешься в самой предметной области и тем, насколько хорошо понимаешь, как эту предметную область переложить в код…

Промежуточные итоги:

Код под спойлером (осторожно, полотно кода):
import urllib.request
import urllib.error
import urllib.parse
import http.client
import json
import contextlib
import sys
import ssl

SERVER = "serverName"
ADMINLOGIN = 'adminLogin'
ADMINPASS = 'adminPass'

def main():
    adminUser = ADMINLOGIN
    adminPass = ADMINPASS
    server = SERVER
    port = "443"
    folder = "/"
    # action = sys.argv[5]
    serverName = server
    serverPort = port
    
    try:
        expiration = 60
        token = getToken(adminUser, adminPass, server, port, expiration)
        
        folderURL = "/arcgis/admin/services/" + folder
        params = urllib.parse.urlencode({'token': token, 'f': 'json'})
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
        httpConn = http.client.HTTPSConnection(serverName, serverPort)
        httpConn.request("POST", folderURL, params, headers)
        response = httpConn.getresponse()
        if (response.status != 200):
            httpConn.close()
            print("Could not read folder information.")
            return
        else:
            data = response.read()

        if not assertJsonSuccess(data):          
            print ("Error when reading folder information. " + str(data))
        else:
            print("Processed folder information successfully. Now processing services...")

        dataObj = json.loads(data)
        httpConn.close()
        
        services = getServices(dataObj)
        for service in services:
            fullSvcName = service['serviceName'] + "." + service['type']
            print(fullSvcName)

        return
    
    except Exception as err:
        print(err)

def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        print ("Error: JSON object returns an error. " + str(obj))
        return False
    else:
        return True

def submit_request(request):
    with contextlib.closing(urllib.request.urlopen(request, context=ssl._create_unverified_context())) as response:
        content = response.read()
        content_decoded = content.decode("utf-8")
        job_info = json.loads(content_decoded)
        return job_info

def getToken(adminUser, adminPass, server, port, expiration):
    token_url = "https://{}:{}/arcgis/admin/generateToken?f=json".format(server, port)
    
    query_dict = {
        'username': adminUser,
        'password': adminPass,
        'expiration': str(expiration),
        'client': 'requestip'
    }

    data = urllib.parse.urlencode(query_dict)
    data_encoded = data.encode("utf-8")
    request = urllib.request.Request(token_url, data=data_encoded)
    token_response = submit_request(request)
    if "token" in token_response:
        print("Getting token...")
        token = token_response.get("token")
        return token
    else:
        if "error" in token_response:
            error_mess = token_response.get("error", {}).get("message")
            if "This request needs to be made over https." in error_mess:
                token_url = token_url.replace("http://", "https://")
                token = getToken(token_url, adminUser, adminPass)
                return token
            else:
                raise Exception("Portal error: {} ".format(error_mess))

def serviceStartStop(server, port, svc, action, token):
    url = "https://{}:{}/arcgis/admin".format(server, port)
    requestURL = url + "/services/{}/{}".format(svc, action)
    
    query_dict = {
        "token": token,
        "f": "json"
    }

    data = urllib.parse.urlencode(query_dict)
    data_encoded = data.encode("utf-8")
    request = urllib.request.Request(requestURL, data=data_encoded)

    with contextlib.closing(urllib.request.urlopen(request, context=ssl._create_unverified_context())) as jsonResponse:
        return json.loads(jsonResponse.read())

def getServices(dataObj):
    services = []
    for item in dataObj['services']:
        services.append(item)
    return services


if __name__ == '__main__':
    ssl._create_default_https_context = ssl._create_unverified_context
    main()

Успешно получаю токен, захожу на сервер и получаю список слоёв:

Попытки получить рабочий вариант скрипта, возвращающего статус сервиса не увенчались успехом:

Назад, к Arcgis API for Python

Решил вернуться к Arcgis API for Python, используя полученные выше результаты, в частности, описание строки подключения и получения токена. 

Прошу ChatGPT сформировать пример. Добавляю получение учётных данных при помощи keyring (не зря же я его использовал ранее).

Пример кода тут:
from arcgis.gis.server import Server
import keyring

# получаю данные админа
ADMIN = keyring.get_credential(service_name="Admin", username=None)
ADMINLOGIN = ADMIN.username
ADMINPASS = ADMIN.password

# сервер
SERVER = "server_name"

# формирую строки
baseUrl = f"https://{SERVER}/arcgis"
url_admin = f"{baseUrl}/admin"
url_token = f"{baseUrl}/tokens/generateToken"

# запрос на подключение
my_server = Server(
    url=url_admin,
    token_url=url_token,
    username=ADMINLOGIN,
    password=ADMINPASS,
    all_ssl=True
)

# поиск сервиса по списку сервисов и получение его статусов
my_services_list = my_server.services.list()
for my_service in my_services_list:
    if my_service.properties["serviceName"] == "SERVICENAME":
        print(my_service, my_service.properties["serviceName"])
        print(my_service.status)

…и результат:

Что я имею сейчас:

Arcgis API for Python даёт необходимый набор инструментов для работы с Arcgis Server. 

Что хорошо: я нашёл в документации и протестировал, как запускать, останавливать, удалять или “создавать” новые сервисы. 

Смог получить доступ к логам Arcgis Server.

Дьявол, как всегда, кроется в деталях

А точнее в процессах ArcSOC.exe.

Детали в том, что определить, к какому экземпляру сервиса относится конкретный ArcSOC можно, либо если получить актуальный Process ID сервиса и найти среди ArcSOC такой, PID которого равен предоставленному Process ID сервиса, либо получив доступ к атрибуту cmdline у ArcSOC. 

И логи – это не мой случай, по крайней мере сейчас. 

Потому что Process ID можно обнаружить только в сообщениях типа Warning или Severe (severe ошибки – это всё, мой сервис завис/упал в ошибку/ему не хватает памяти), а после таких сообщений сервис, как правило, будет перезапущен и его Process ID изменится.

Уже после начала реализации решения через cmdline я наткнулся на информацию о том, что чтобы получать полную информацию в логах, необходимо выставить их уровень записи FINE. К сожалению, проверять, какой уровень выставлен, сейчас времени нет.

Сmdline

Доступа к просмотру cmdline у меня, конечно же, не было. И, несмотря на то, что был виден горизонт решения проблемы и мне было невтерпёж его реализовать, я преисполнился ожиданием:

Но и этот рубеж был пройден.

Пример запроса к cmdline:
import psutil

def get_arcsoc_state(service_name):
    '''function to get PID, name, memory and CPU used by ArcSOC.exe process'''
    
    state_list = []
    for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
        if proc.info['name'] == 'ArcSOC.exe':
            cmdline = ' '.join(proc.info['cmdline'])
            if service_name in cmdline:
                # Get memory and CPU usage
                memory_usage = proc.memory_percent()
                cpu_usage = proc.cpu_percent(interval=1)
                state_list.append((proc.info['pid'],  proc.info['name'], memory_usage, cpu_usage))
    return state_list

service_name = 'PrintServ'
states = get_arcgis_service_pid(service_name)
print(f'Process state for {service_name}: {states}')

И результат:

Дальнейшие действия

Сбор скрипта и настройка его работы в первом приближении выглядит так:

  1. Создаю credential запись с логином и паролем администратора ArcGIS.

  2. Описываю в скрипте проверку состояния ArcSOC.exe и необходимую логику реагирования на инциденты.

  3. Создаю в скрипте подключение к ArcGIS сервер и описываю реагирования на тот или иной инцидент с ArcSOC.exe.

  4. Создаю в Task Scheduler событие по расписанию и запуск события с правами администратора.

Про LLM и AI

Безусловно удобный инструмент. Сокращает интервал между стартом вашего поиска какой-либо информации и получением ответа в виде этой информации или же чего-то иного. 

Кажется, уже нет смысла писать хвалебные оды AI: тот кто проникся, тот уже и так всё понимает. Тот, кто до сих пор считает AI игрушкой, которая только и может давать неправильные и вредные советы – в начале 2023 года, возможно, так и было. Сейчас, в начале 2024 года, AI может стать полноценным помощником для таких как я – имеющих компетенции в предметной области, но не имеющих достаточного опыта в разработке.

Конец

На этом я заканчиваю эту статью, целью которой было показать процесс поиска решения всеми подручными средствами, какие у меня были. У меня есть доступ к библиотеке ArcGis API for Python и доступ к cmdline, что позволит мне управлять сервисами ArcGis Server так, как этого будет требовать ситуация.  

Честно говоря, идеи и их реализация, которые сейчас у меня в голове, тянут уже не на скрипт, а на полноценное решение: с логированием, рассылкой отчётов по почте коллегам, создание GUI для простого и быстрого доступа к перезапуску сервисов ArcGis для коллег, которые не имеют доступа к task manager или не имеют компетенций для перезапуска сервиса печати Printing tools из меню ArcGis for Desktop и т. д.

Описание этого процесса разработки тянет на отдельную статью. 

Спасибо всем дочитавшим до конца. Надеюсь, статья была полезной.

Tags:
Hubs:
Total votes 3: ↑3 and ↓0+3
Comments10

Articles

Information

Website
www.x5.ru
Registered
Founded
2006
Employees
over 10,000 employees
Location
Россия