В этой статье мы научимся хранить данные о сеансах консоли кластеров 1С в СУБД, вынимать и агрегировать информацию о лицензиях.
upd. 2025.12.19
обновил главный файл сбора данных — зафиксировал, что регулярное выражение покрывало не все сеансы.
Имплементация системы мониторинга кластера 1С (и лицензий).
Для успешного приготовления нам потребуются:
-
1С Предприятие нужного Вам релиза.
-
Linux* (я использую CentOS 7.5)
-
Grafana* ( я использую версию 5.2.4)
-
Postgres Pro* (у меня сейчас 10.6.1)
-
Python (у меня 3.6.*)
*Вопросы установки Linux, Grafana и Postgre Pro в данной статье не будут рассмотрены.
Сначала коснёмся 1С. Для сбора данных через RAS нам нужно:
-
Установить(и запустить) службу RAS на серверах приложений 1С под Windows. Через RAS мы будем получать данные от этого СП 1С. Установить службу можно сделать такой командой:
"C:WindowsSystem32sc.exe" create "1C:Remote Administation Serive (RAS)" binPath= ""C:Program Files1cv88.3.12.1685in
as.exe" cluster —service —port=1545 ИМЯ_СЕРВЕРА:1540" start= auto
as.exe" cluster —service —port=1545 ИМЯ_СЕРВЕРА:1540" start= auto
Для автоматической установки службы RAS можно воспользоваться скриптом func.install_ras.ps1 из раздела загрузки.
-
Установить необходимые компоненты 1С rac на Linux.Для CentOS потребуется потребуется скачать с https://releases.1c.ru/ Сервер 1С:Предприятия (64-bit) для RPM-based Linux-систем.Порядок установки пакетов, на примере релиза 8.3.12.1685 для моей ОС следующий:
yum install -y 1C_Enterprise83-common-8.3.12-1685.x86_64.rpm
yum install -y 1C_Enterprise83-common-nls-8.3.12-1685.x86_64.rpm
yum install -y 1C_Enterprise83-server-8.3.12-1685.x86_64.rpm
yum install -y 1C_Enterprise83-server-nls-8.3.12-1685.x86_64.rpm
После этого rac будет доступен из /opt/1C/v8.3/x86_64/rac.
-
Проверить корректность установки можно подключившись к RAS.
/opt/1C/v8.3/x86_64/rac cluster list ИМЯ_СЕРВЕРА:1545
Если всё правильно, то мы увидим подобное:
Теперь подготовим отдельную базу в Postgre.
В ней нам потребуется несколько таблиц:
-
Таблица для хранения списка серверов RAS, к которым мы будет подключаться за данными.
-
Вспомогательные таблицы для экономии места
-
Таблица данных о сеансах.
Подключаемся к postgre из консоли:
su postgres
psql
Создаём пользователя для работы со своей базой данных:
CREATE ROLE "racer" LOGIN PASSWORD ‘my_evil_password’;
Создаём отдельную базу данных:
CREATE DATABASE "racerDB"
WITH
OWNER = "racer"
ENCODING = ‘UTF8’
LC_COLLATE = ‘ru_RU.UTF-8@icu.58.0.0.50’
LC_CTYPE = ‘ru_RU.UTF-8’
TABLESPACE = "pg_default"
;
connect racerDB;
Создаём таблицу для хранения списка RAS-серверов, к которым будем подключаться:
CREATE TABLE "public"."ras_servers" (
"id" SERIAL PRIMARY KEY,
"host_name" varchar(255) NOT NULL,
"ras_port" int2 NOT NULL
);
ALTER TABLE "public"."ras_servers"
OWNER TO "racer";
И заполняем её списком своих RAS-серверов:
INSERT INTO "public"."ras_servers"("host_name", "ras_port") VALUES (‘ИМЯ_СЕРВЕРА_1’, 1545) RETURNING *;
INSERT INTO "public"."ras_servers"("host_name", "ras_port") VALUES (‘ИМЯ_СЕРВЕРА_2’, 1545) RETURNING *;
…
INSERT INTO "public"."ras_servers"("host_name", "ras_port") VALUES (‘ИМЯ_СЕРВЕРА_N’, 1545) RETURNING *;
Теперь нам нужно создать несколько служебных таблиц, чтобы хранить в них ссылки на данные из главной таблицы соединений.
-
Таблица для хранения списка пользователей
CREATE TABLE "public"."users" (
"id" SERIAL PRIMARY KEY,
"name" varchar(255) NOT NULL
);
ALTER TABLE "public"."users"
OWNER TO "racer";
-
Таблица со списком информационных баз
CREATE TABLE "public"."infobases" (
"id" SERIAL PRIMARY KEY,
"uuid" varchar(36) NOT NULL,
"name" varchar(255) NOT NULL,
"descr" varchar(1024)
);
ALTER TABLE "public"."infobases"
OWNER TO "racer";
-
Таблица со списком клиентских ПК
CREATE TABLE "public"."hosts" (
"id" SERIAL PRIMARY KEY,
"name" varchar(255) NOT NULL
);
ALTER TABLE "public"."hosts"
OWNER TO "racer";
-
Таблица со списком лицензий
CREATE TABLE "public"."licenses_db" (
"id" SERIAL PRIMARY KEY,
"name" varchar(255) NOT NULL,
"type" varchar(4) NOT NULL,
"max" int2 NOT NULL
);
ALTER TABLE "public"."licenses_db"
OWNER TO "racer";
-
Таблица со списком приложений 1С
CREATE TABLE "public"."apps" (
"id" SERIAL PRIMARY KEY,
"name" varchar(255) NOT NULL,
"description" varchar(255)
);
ALTER TABLE "public"."apps"
OWNER TO "racer";
—и сразу заполним её
INSERT INTO "public"."apps"("name", "description") VALUES (‘1CV8’, ‘Толстый клиент’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘1CV8C’, ‘Тонкий клиент’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘WebClient’, ‘Веб-клиент’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘Designer’, ‘Конфигуратор’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘COMConnection’, ‘COM-соединение’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘WSConnection’, ‘Сессия веб-сервиса’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘BackgroundJob’, ‘Фоновое задание’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘SystemBackgroundJob ‘, ‘Системное фоновое задание’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘SrvrConsole’, ‘Консоль кластера’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘COMConsole’, ‘COM-консоль кластера’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘JobScheduler ‘, ‘Планировщик’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘Debugger’, ‘Отладчик’) RETURNING *;
INSERT INTO "public"."apps"("name", "description") VALUES (‘RAS’, ‘Сервер администрирования’) RETURNING *;
-
Таблица со списком процессов сервера 1С. В ней будет храниться неизменяемая информация о процессах СП 1С (она нужна нам для получения имени рабочего сервера для сессии)
CREATE TABLE "public"."processes" (
"id" SERIAL PRIMARY KEY,
"uuid" varchar(36) NOT NULL,
"host" varchar(255),
"port" int4,
"pid" int4,
"started_at" timestamp
);
ALTER TABLE "public"."processes"
OWNER TO "racer";
Теперь создаём таблицу, в которой будем хранить информацию о соединениях и их лицензиях.
CREATE TABLE "public"."sessions" (
"ras_server_by_id" int2 NOT NULL, —ссылка на имя RAS-сервера, с которого были получены данные
FOREIGN KEY("ras_server_by_id") REFERENCES hosts(id) ON DELETE SET DEFAULT, —ссылка на имя RAS-сервера, с которого были получены данные
"datetime" timestamp NOT NULL, —дата и время получения среза в UTC
"session-id_nmb" int4 NOT NULL, —номер сессии
"infobase_by_id" int2 NOT NULL, —id информационной базы из таблицы infobases
FOREIGN KEY("infobase_by_id") REFERENCES infobases(id) ON DELETE SET DEFAULT, —id информационной базы из таблицы infobases
"process_by_id" int4 , —id процесс СП 1C из таблицы processes
FOREIGN KEY("process_by_id") REFERENCES processes(id) ON DELETE SET DEFAULT, —id процесс СП 1C из таблицы processes
"user-name_by_id" int2 NOT NULL, —id пользователя из таблицы users
FOREIGN KEY("user-name_by_id") REFERENCES users(id) ON DELETE SET DEFAULT, —id пользователя из таблицы users
"host_by_id" int2 NOT NULL, —id хоста пользователя
FOREIGN KEY("host_by_id") REFERENCES hosts(id) ON DELETE SET DEFAULT, —id хоста пользователя
"app-id_by_id" int2 NOT NULL, —id приложения из таблицы apps
FOREIGN KEY("app-id_by_id") REFERENCES apps(id) ON DELETE SET DEFAULT, —id приложения из таблицы apps
"started-at" timestamp NOT NULL, —дата и время начала сеанса в UTC
"last-active-at" timestamp NOT NULL, —последняя активность
"hibernate" bool NOT NULL, —спящий ли сеанс
"passive-session-hibernate-time" int4 NOT NULL, —
"hibernate-session-terminate-time" int4 NOT NULL, —
"blocked-by-dbms" int4 NOT NULL, —
"blocked-by-ls" int4 NOT NULL, —
"bytes-all" int8 NOT NULL, —
"bytes-last-5min" int8 NOT NULL, —
"calls-all" int4 NOT NULL, —
"calls-last-5min" int4 NOT NULL, —
"dbms-bytes-all" int8 NOT NULL, —
"dbms-bytes-last-5min" int8 NOT NULL, —
"db-proc-info" int4 NOT NULL, —
"db-proc-took" int4 NOT NULL, —
"db-proc-took-at" timestamp , —
"duration-all" int4 NOT NULL, —
"duration-all-dbms" int4 NOT NULL, —
"duration-current" int4 NOT NULL, —
"duration-current-dbms" int4 NOT NULL, —
"duration-last-5min" int4 NOT NULL, —
"duration-last-5min-dbms" int4 NOT NULL, —
"memory-current" int8 NOT NULL, —
"memory-last-5min" int8 NOT NULL, —
"memory-total" int8 NOT NULL, —
"read-current" int8 NOT NULL, —
"read-last-5min" int8 NOT NULL, —
"read-total" int8 NOT NULL, —
"write-current" int8 NOT NULL, —
"write-last-5min" int8 NOT NULL, —
"write-total" int8 NOT NULL, —
"duration-current-service" int4 NOT NULL, —
"duration-last-5min-service" int4 NOT NULL, —
"duration-all-service" int4 NOT NULL, —
"license_by_id" int2 , —размер ключа (на сколько он пользователей)
FOREIGN KEY("license_by_id") REFERENCES licenses_db(id) ON DELETE SET DEFAULT, —размер ключа (на сколько он пользователей)
"license_issued_by_server" bool , —признак выдачи лицензии сервером
"license_net" bool , —сетевая ли лицензия
"rmngr_by_id" int2 , —хост, выдавший лицензию
FOREIGN KEY("rmngr_by_id") REFERENCES hosts(id) ON DELETE SET DEFAULT —хост, выдавший лицензию
);
ALTER TABLE "public"."sessions"
OWNER TO "racer";
CREATE INDEX "by_date" ON "public"."sessions" USING btree (
"datetime" "pg_catalog"."timestamp_ops" ASC NULLS LAST
);
Так как в таблице хранятся ссылки, а не абсолютные значения, создадим для удобства просмотров, агрегированный view_sessions, содержащий значения всех всех собранных данных:
CREATE VIEW "public"."view_sessions" AS
SELECT
h1.name AS ras_host
, s.datetime AS datetime
, s."session-id_nmb" AS session_id
, i.name AS infobase_name
, p.host AS process_host
, p.port AS process_port
, p.pid AS process_pid
, p.started_at AS process_started
, u.name AS user_name
, h2.name AS user_host
, a.name AS app
, s."started-at" AS started_at
, s."last-active-at" AS last_active_at
, s.hibernate AS hibernate
, s."passive-session-hibernate-time" AS passive_session_hibernate_time
, s."hibernate-session-terminate-time" AS hibernate_session_terminate_time
, s."blocked-by-dbms" AS blocked_by_dbms
, s."blocked-by-ls" AS blocked_by_ls
, s."bytes-all" AS bytes_all
, s."bytes-last-5min" AS bytes_last_5min
, s."calls-all" AS calls_all
, s."calls-last-5min" AS calls_last_5min
, s."dbms-bytes-all" AS dbms_bytes_all
, s."dbms-bytes-last-5min" AS dbms_bytes_last_5min
, s."db-proc-info" AS db_proc_info
, s."db-proc-took" AS db_proc_took
, s."db-proc-took-at" AS db_proc_took_at
, s."duration-all" AS duration_all
, s."duration-all-dbms" AS duration_all_dbms
, s."duration-current" AS duration_current
, s."duration-current-dbms" AS duration_current_dbms
, s."duration-last-5min" AS duration_last_5min
, s."duration-last-5min-dbms" AS duration_last_5min_dbms
, s."memory-current" AS memory_current
, s."memory-last-5min" AS memory_last_5min
, s."memory-total" AS memory_total
, s."read-current" AS read_current
, s."read-last-5min" AS read_last_5min
, s."read-total" AS read_total
, s."write-current" AS write_current
, s."write-last-5min" AS write_last_5min
, s."write-total" AS write_total
, s."duration-current-service" AS duration_current_service
, s."duration-last-5min-service" AS duration_last_5min_service
, s."duration-all-service" AS duration_all_service
, l.name AS license_series
, l.type AS license_type
, l.max AS license_max
, s.license_issued_by_server AS license_issued_by_server
, s.license_net AS license_net
, h3.name AS license_rmngr
FROM
sessions s
LEFT JOIN hosts h1 ON s.ras_server_by_id = h1.id
LEFT JOIN infobases i ON s.infobase_by_id = i.id
LEFT JOIN processes p ON s.process_by_id = p.id
LEFT JOIN users u ON s."user-name_by_id" = u.id
LEFT JOIN hosts h2 ON s.host_by_id = h2.id
LEFT JOIN apps a ON s."app-id_by_id" = a.id
LEFT JOIN licenses_db l ON s.license_by_id = l.id
LEFT JOIN hosts h3 ON s.rmngr_by_id = h3.id
;
ALTER TABLE "public"."view_sessions"
OWNER TO "racer";
Для выборки данных о лицензиях нам понадобится отдельный View, ибо с использованием лицензий не всё так просто.
1С утилизирует лицензии полученные клиентом и выданные сервером по разному:
-
при выдаче сервером для каждого сеанса выдаётся одна программная лицензия;
-
при выдаче сервером для каждого сеанса выдаётся одна аппаратная лицензия;
-
при выдаче клиентскому приложению службой HASP LM для каждого пользовательского сеанса(сессия RDP или локальное подключение Windows) на клиенте выдаётся одна аппаратная лицензия. При этом с этой одной лицензией можно работать в разных базах.
-
как считать программные лицензии, полученные локально клиентским приложением я ещё не определился, к ним применяется такой же порядок, как для аппаратных, выданных клиенту.
Из-за этих особенностей в отборе применяется три вида группировки:
-
для серверов, не являющихся терминальными (отбираются через view_not_terminal_ids) агрегируются все подключения с каждого хоста для каждого уникального ключа;
-
для терминальных серверов (view_terminal_ids) применяется дополнительная агрегация и по имени пользователя — применяется допущение, что пользователь, работающий из терминальной сессии в разных базах, будет работать там под одним именем;
-
и наконец, для лицензий, выданных сервером, не применяется никакой группировки.
Сначала определимся со списком рабочих станций, не являющихся терминальными серверами:
CREATE VIEW view_not_terminal_ids AS
SELECT h.id from HOSTS h
WHERE
(UPPER (( h.NAME ) :: TEXT ) !~~ ‘TERM%’ :: TEXT)
AND
(UPPER (( h.NAME ) :: TEXT ) !~~ ‘APP%’ :: TEXT)
;
ALTER TABLE "public"."view_not_terminal_ids"
OWNER TO "racer";
Потом — со списком терминальных серверов:
CREATE VIEW view_terminal_ids AS
SELECT h.id from HOSTS h
WHERE
(UPPER (( h.NAME ) :: TEXT ) ~~ ‘TERM%’ :: TEXT)
OR
(UPPER (( h.NAME ) :: TEXT ) ~~ ‘APP%’ :: TEXT)
;
ALTER TABLE "public"."view_terminal_ids"
OWNER TO "racer";
Теперь можно создавать View с группировкой использования лицензий:
CREATE VIEW "public"."view_licenses" AS
SELECT
s.datetime
, » :: TEXT AS user_name
, UPPER (( h.NAME ) :: TEXT ) AS user_host
, » :: TEXT AS appid
, l.NAME AS license_series
, s.license_issued_by_server AS license_issued_by_server
, s.license_net AS license_net
, l.TYPE AS license_type
, » AS license_rmngr —у клиентских не будет RMNGR
, l.MAX AS license_max
, COUNT ( * ) AS seanses_count —сеансов на эту лицензию
FROM
sessions s
LEFT JOIN hosts h ON s.host_by_id = h.ID
LEFT JOIN licenses_db l ON s.license_by_id = l.ID
LEFT JOIN users u ON s."user-name_by_id" = u.ID
WHERE
(s.license_issued_by_server = FALSE) —только лицензии, не выданные сервером
AND
(s.host_by_id in (select id from view_not_terminal_ids)) —и не с терминальных серверов
GROUP BY —группируем по
s.datetime
, ( UPPER (( h.NAME ) :: TEXT )) —имени хоста
, l.NAME —серии лицензии
, s.license_issued_by_server —признаку выдачи сервером
, s.license_net —является ли лицензия сетевой
, l.TYPE —типу — приграммная/аппаратная
, l.MAX —размеру ключа
UNION ALL
SELECT
s.datetime
, UPPER (( u.NAME ) :: TEXT ) AS user_name
, UPPER (( h.NAME ) :: TEXT ) AS user_host
, » :: TEXT AS appid
, l.NAME AS license_series
, s.license_issued_by_server AS license_issued_by_server
, s.license_net AS license_net
, l.TYPE AS license_type
, » AS license_rmngr —у клиентских не будет RMNGR
, l.MAX AS license_max
, COUNT ( * ) AS seanses_count —сеансов на эту лицензию
FROM
sessions s
LEFT JOIN hosts h ON s.host_by_id = h.ID
LEFT JOIN licenses_db l ON s.license_by_id = l.ID
LEFT JOIN users u ON s."user-name_by_id" = u.ID
WHERE
(s.license_issued_by_server = FALSE) —только лицензии, не выданные сервером
AND
(s.host_by_id in (select id from view_terminal_ids)) —с терминальных серверов
GROUP BY
s.datetime
, ( UPPER (( u.NAME ) :: TEXT )) —добавляем группировку по имени пользователя
, ( UPPER (( h.NAME ) :: TEXT )) —имени хоста
, l.NAME —серии лицензии
, s.license_issued_by_server —признаку выдачи сервером
, s.license_net —является ли лицензия сетевой
, l.TYPE —типу — приграммная/аппаратная
, l.MAX —размеру ключа
UNION ALL
SELECT
s.datetime
, UPPER (( u.NAME ) :: TEXT ) AS user_name
, UPPER (( h.NAME ) :: TEXT ) AS user_host
, A.NAME AS appid
, l.NAME AS license_series
, s.license_issued_by_server AS license_issued_by_server
, s.license_net AS license_net
, l.TYPE AS license_type
, UPPER (( h2.NAME ) :: TEXT )AS license_rmngr —а здесь RMNGR будет
, l.MAX AS license_max
, ‘1’ :: BIGINT AS seanses_count —сеансов на эту лицензию
FROM
sessions s
LEFT JOIN hosts h ON s.host_by_id = h.ID
LEFT JOIN licenses_db l ON s.license_by_id = l.ID
LEFT JOIN users u ON s."user-name_by_id" = u.ID
LEFT JOIN apps a ON s."app-id_by_id" = A.ID
LEFT JOIN hosts h2 ON s.rmngr_by_id = h2.ID
WHERE
s.license_issued_by_server = TRUE —все лицензии выданные сервером не группируются
;
ALTER TABLE "public"."view_licenses"
OWNER TO "racer";
Подготовка хранилища данных завершена.
Собираем данные
Сначала о командах, используемых для получения информации:
-
/opt/1C/v8.3/x86_64/rac cluster list ИМЯ_СЕРВЕРА:1545 #так мы будем получать список кластеров из сервера RAS
-
/opt/1C/v8.3/x86_64/rac infobase summary list —cluster=GUID_Кластера ИМЯ_СЕРВЕРА:1545 #здесь мы, используя GUID кластера из первой команды, получим список баз
-
/opt/1C/v8.3/x86_64/rac process list —cluster=GUID_Кластера ИМЯ_СЕРВЕРА:1545 #а так мы получим информацию о списке рабочих процессов
-
/opt/1C/v8.3/x86_64/rac session list —cluster=GUID_Кластера ИМЯ_СЕРВЕРА:1545 #с помощью этой команды можно получить список сеансов, но здесь есть не вся информация о лицензии
-
/opt/1C/v8.3/x86_64/rac session list —licenses —cluster=GUID_Кластера ИМЯ_СЕРВЕРА:1545 #а тут мы получаем недостающую информацию о лицензиях
Общий порядок работы скрипта такой:
-
Получаем список кластеров сервера RAS из таблицы ras_servers в базе Postre
-
Получаем список информационных баз кластера
-
Получаем список процессов кластера
-
Получаем список сеансов и их лицензий
-
Сводим все данные и заносим в целевую таблицу
Проверим, что у нас установлен Python 3.6
yum list installed | grep python36
Если его нет, то нужно его поставить:
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
yum install -y python36u python36u-devel python36u-pip
И, в любом случае, нужно поставить два используемых модуля Python:
pip3.6 install psycopg2
pip3.6 install pytz
После этого нужно настроить скрипт сбора данных (см. раздел загружаемых файлов) — отредактировать его и поменять параметры подключения к Postre.
postgre_host = "localhost"
postgre_port = "5432"
postgre_database = "racerDB"
postgre_database_user = "racer"
postgre_database_user_password = "password"
И проверить корректность всех настроек, запустив его сразу из консоли:
/usr/bin/python3.6 /root/pyrac1c.py
Если до этого всё сделано правильно, то можно его в планировщик:
crontab -l | { while IFS= read -ra tasks; do printf ‘%s
‘ "$tasks"; done; echo ‘*/10 * * * * /usr/bin/python3.6 /root/pyrac1c.py > /dev/null 2>&1’;} | crontab #добавляем к списку заданий /usr/bin/python3.6 /root/pyrac1c.py для запуска через каждые 10 минут
‘ "$tasks"; done; echo ‘*/10 * * * * /usr/bin/python3.6 /root/pyrac1c.py > /dev/null 2>&1’;} | crontab #добавляем к списку заданий /usr/bin/python3.6 /root/pyrac1c.py для запуска через каждые 10 минут
У нас уже начали собираться данные, самое время отправиться в Grafana и настроить графики.
Сначала нужно добавить новый DataSource с типом PostgreSQL и данными для подключения к нашему серверу с данными:
После этого можно смело создавать новый Dashboard и добавлять на него первый Graph
Выбираете свой Datasource на вкладке Metrics и можно редактировать тексты запросов.
В качестве первого запроса агрегируем информацию об утилизации лицензий:
—всего утилизировано лицензий
SELECT
$__timeGroup(DATETIME, ’10m’,0) as "time",
—DATETIME,
COUNT(*) AS "Утилизировано лиц. всего."
FROM view_licenses l
GROUP BY l.datetime
ORDER BY l.datetime asc
Сделаем отдельный график для лицензий, утилизированный сервером и клиентом 1С:
—утилизировано серверных и клиентских
SELECT
$__timeGroup(l.datetime, ’10m’,0),
—l.datetime,
CASE
WHEN l.license_issued_by_server=true THEN ‘Утилизировано серверных’
WHEN l.license_issued_by_server=false THEN ‘Утилизировано клиентских’
END,
COUNT(*)
FROM view_licenses l
GROUP BY l.datetime,l.license_issued_by_server
ORDER BY l.datetime asc
Узнаем, сколько же всего у нас сеансов с лицензий:
—сеансы с лицензией
SELECT
$__timeGroup(s.datetime,10m,0),
—s.datetime,
COUNT(*) as "Сеансов с лицензией"
FROM
sessions s
WHERE s.license_by_id is not null
GROUP BY s.datetime
ORDER BY s.datetime
И сколько из них получило лицензию на сервере или на клиенте:
—сеансы с программными или аппаратными лицензиями
SELECT
$__timeGroup(s.datetime, ’10m’,0),
—s.datetime,
CASE
WHEN s.license_issued_by_server=true THEN ‘Сеансов с лицензией от сервера’
WHEN s.license_issued_by_server=false THEN ‘Сеансов с лицензий от клиента’
END,
COUNT(*)
FROM sessions s
WHERE s.license_issued_by_server is not null and s.license_by_id is not null
GROUP BY s.datetime,s.license_issued_by_server
ORDER BY s.datetime asc
Отдельный график можно сделать и по сеансам с программными и аппаратными лицензиями:
—Сеансы программных и аппаратных лицензий
SELECT
$__timeGroup(DATETIME, ’10m’,0),
—s.DATETIME,
‘Сеансов с лицензией ‘||l.type,
COUNT(*)
FROM
sessions s, licenses_db l
where l.id = s.license_by_id
GROUP BY s.datetime,l.type
ORDER BY s.datetime asc
И посмотреть утилизацию ключей по типам (обратите внимание, что многопользовательские ключи на 20, 50 и 100 лицензий обладают одинаковым идентификатором — ORGL8. А ещё для клиентских лицензий мы не может узнать какой HASP LM их выдал, поэтому они агрегируются сразу по всем ключам одного типа и значение для графика таких ключей может быть больше ёмкости одного ключа):
—утилизацию по типам ключей
SELECT
$__timeGroup(l.datetime,10m, 0) AS "time"
—l.datetime as datetime
,case
when l.license_issued_by_server then
‘server ‘||l.license_type||’-‘||l.license_series||'(‘||l.license_max||’) by ‘|| l.license_rmngr
else
‘client ‘||l.license_type||’-‘||l.license_series||'(‘||l.license_max||’)’
end AS license_data
,count(*)
FROM view_licenses l
GROUP BY l.datetime,license_data
ORDER BY l.datetime,license_data asc
Напоследок, можем посмотреть и сколько у нас спящих сеансов:
—спящие сеансы
SELECT
$__timeGroup(s.datetime,10m,0),
—s.datetime,
COUNT(*) as "Спящие сеансы"
FROM
sessions s
WHERE s.hibernate = TRUE
GROUP BY s.datetime
ORDER BY s.datetime
На выходе получаются вот такие прекрасные графики.
Весь процесс сбора данных есть в ЦКК. Немного его допиливаем, а логику аггрегации лицензий выносим в отчет. Или в алгоритм заполнения мониторинговой БД, если используется сторонняя система мониторинга. В частности, я шлю в Zabbix посредством ВК, реализующей Zabbix sender.
Хороший, навороченный, но сложный велосипед.
(1) а зачем через ВК в Zabbix слать? Он может сам дергать агента и получать инфу
(2) Спасибо за оценку. Я поэтому и описал подробно, чтобы самому всё уложить в голове )))
Может это и велосипед, не знаю.
Но велосипед боевой )
Как совет — по хорошему надо просто серверам ограничить доступ к аппаратным лицензиям.
Уберете путаницу и количество свободных лицензий увеличите
(3) Так экономнее: агент сам по себе в 1С ходить не умеет, типовое решение — агент читает stdout дочернего процесса. Который еще нужно запустить, потратив на это системные ресурсы.
(6) если агентом дергать rac- не сильно то и затратнее
У в качестве центра мониторинга — Zabbix. Он сразу избавляет вас от 2,4,5 пукнта. Плюс есть агент, который сам отправляет данные серверу.
Мониторинг «железных» лицензий прямо на хосте, где они установлены. Так честнее и проще.
Ну и графана для красоты (sql-запросы пилить не надо, так как есть интеграция с заббиксом, — достаточно выбрать показатель/item).
(8) Мониторинг железных ключей — это хорошо. Но он работает у Вас только под Win.
И ещё — если выдаёте железные ключи сервером, то вы не знаете, сколько их выдано. Ибо эти данные не получить из ключа, увы.
Буду рад, если опровергните меня по любому из пунктов.
В конце хочу добавить, что данный мониторинг не ограничивается только лишь ключами 😉
О разнообразии применений собираемых данных, по мере накопления UseCases, напишу ещё одну статью.
(9)
Буду рад, если опровергните меня по любому из пунктов.
Здесь у многих заблуждение. Да, в списке сессий будет видна только одна запись самого сервера 1С, но ключ же как-то понимает сколько ключей он раздал. Эта цифра (без детализации по хостам) видна и в аладдиновском мониторе, и может быть получена программно, используя dll-ку.
Кросплатформенность сейчас, конечно, в моде, но не настолько, чтобы фанатично первым делом переходить на линукс. Впрочем, это Ваши предпочтения и требования.
Я за более взвешенный подход: использовать то, что лучше и удобнее для каждой конкретной задачи. Возможно, у Вас так, но из статьи этого не видно.
Аналогично.
(10)
Либо я чего-то не знаю, либо Вы.
Я утверждаю (и мои слова подкреплены ответом из 1С) о том, что получить количество утилизированных СП 1С лицензий из аппаратного ключа средствами, в первую очередь, Alladdin Monitor, нельзя.
Можете показать как вы получаете количество выданных СП 1С лицензий из многопользовательского ключа HASP?
По поводу остальных выводов и заключений:
1. Для меня перспектива — кроссплатформенность. Делать сейчас одно, а потом переделывать в другое можно. Но это не мой выбор.
2. Расскажите о том, как сделано у Вас. Мне очень интересно.
(11)
Конечно, оно так. Но нужно помнить один нюанс. Занятые лицензии не увидеть, если Ваш ключ воткнут непосредственно в сервер 1С. Тогда получение лицензии идет мимо службы HASP.
А, вот, если для ключа выделить отдельную машину (мы, например, по серверам СУБД распихали), то правильное количество лицензий начнет показывать даже Alladdin Monitor. Собственно, так используем и мониторим.
(11)
Так я уже написал в первом посте. Zabbix используются для мониторинга железа, операционной системы, а мы туда еще простенькими PowerShell коммандлетами пропихиваем свои метрики бизнес-приложения.
Я тут америку не открыл и рекламировать это смысла не вижу. Это все равно что запилить статью, например, о том как здорово я установил платформу на 50+ пользовательских компьютеров при помощи простеньких команд.
Свои собственный решения хороши тем, что в них у Вас полная уверенность. Но передать другому специалисту их нельзя. Он их выбросит и напишет свои скрипты. На Заббикс в данном случае нужно смотреть как на универсальный и мощный инструмент, своего рода Платформа, которая уже из коробки может очень многое. Плюс всегда есть Агент, который сам выполнит скрипт и будет сообщать об ошибках. А если машина ушла в небытие, то о недоступности Агента сообщит уже Сервер. И, если не прикручивать к нему для красоты Графану, то одного Заббикса будет уже достаточно.
(12)
А, вот, если для ключа выделить отдельную машину (мы, например, по серверам СУБД распихали), то правильное количество лицензий начнет показывать даже Alladdin Monitor. Собственно, так используем и мониторим.
Я знаю о трёх способах выдачи лицензий сервером приложений 1С:
1. Выдачи из ключа под сервером. Этот способ используется всегда первым. Есть ли служба nethasp, нет ли её, СП 1С всегда начинает выдавать лицензии из ключа под собой.
2. Программные лицензии. Здесь всё просто и очевидно. Нечего и добавить.
3. Лицензии из сетевого ключа (прописанного в nethasp.ini). И вот здесь, увы, Alladdin Monitor бессилен. Он показывает корректно только лицензии, полученные клиентом. А лицензии, выданные СП 1С он не покажет верно. Можете проверить. Это так. И 1С это подтверждает.
Zabbix я тоже использую. Но не для метрик работы 2000 сеансов. Это чрезвычайно избыточно — хранить все эти данные в Zabbix. Совершенство в многообразии.
(13)
Все уже проверено до Вас. Просто Вы неверно поняли то, что написала 1С и корректировать свою точку зрения не хотите.
(14) То, что Вы видите соединения от сервера в ключе, не значит, что Вы видите количество утилизированных ключей ))
И да, я действительно не хочу корректировать свою точку зрения. Просто потому, что я проверял внимательней — сравнивал количество записей в Alladdin Monitor с количеством лицензий, утилизированных в консоли администрирования.
Мдаа, а ещё с Вашей стороны в высшей степени неразумно делать выводы о понимании мною письма, содержимого которого Вы даже не знаете. Ну что ж, давайте посмотрим вместе:
Если захотите проверить нормально, а не на отъ…сь, то пишите, если посчитаете нужным.
Удачи с математикой 😉