Имплементация системы мониторинга кластеров 1С (и лицензий)

18.12.18

База данных - Инструменты администратора БД

В этой статье мы научимся хранить данные о сеансах консоли кластеров 1С в СУБД, вынимать и агрегировать информацию о лицензиях.

Скачать исходный код

Наименование Файл Версия Размер
Скрипт сбора данных о сеансах в Postgre
.py 56,49Kb
16
.py 1.18.12.19 56,49Kb 16 Скачать
Скрипт автоматического создания службы RAS
.ps1 3,92Kb
11
.ps1 1.18.12.18 3,92Kb 11 Скачать
upd. 2018.12.19
обновил главный файл сбора данных - зафиксировал, что регулярное выражение покрывало не все сеансы.
 
Имплементация системы мониторинга кластера 1С (и лицензий).
 
Для успешного приготовления нам потребуются:
  1. 1С Предприятие нужного Вам релиза.
  2. Linux* (я использую CentOS 7.5)
  3. Grafana* ( я использую версию 5.2.4)
  4. Postgres Pro* (у меня сейчас 10.6.1)
  5. Python (у меня 3.6.*)
 
*Вопросы установки LinuxGrafana и Postgre Pro в данной статье не будут рассмотрены.
 
 
Сначала коснёмся . Для сбора данных через RAS нам нужно:
 
  1. Установить(и запустить) службу RAS на серверах приложений 1С под Windows. Через RAS мы будем получать данные от этого СП . Установить службу можно сделать такой командой:
"C:\Windows\System32\sc.exe" create "1C:Remote Administation Serive (RAS)" binPath= "\"C:\Program Files\1cv8\8.3.12.1685\bin\ras.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.
 
  1. Проверить корректность установки можно подключившись к RAS.
/opt/1C/v8.3/x86_64/rac cluster list ИМЯ_СЕРВЕРА:1545
Если всё правильно, то мы увидим подобное:
 
 
Теперь подготовим отдельную базу в Postgre.
 
В ней нам потребуется несколько таблиц:
  1. Таблица для хранения списка серверов RAS, к которым мы будет подключаться за данными.
  2. Вспомогательные таблицы для экономии места
  3. Таблица данных о сеансах.
 
Подключаемся к 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";
 
  • Таблица со списком приложений
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 *;
 
  • Таблица со списком процессов сервера . В ней будет храниться неизменяемая информация о процессах СП (она нужна нам для получения имени рабочего сервера для сессии)
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, ибо с использованием лицензий не всё так просто.
утилизирует лицензии полученные клиентом и выданные сервером по разному:
  • при выдаче сервером для каждого сеанса выдаётся одна программная лицензия;
  • при выдаче сервером для каждого сеанса выдаётся одна аппаратная лицензия;
  • при выдаче клиентскому приложению службой 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   #а тут мы получаем недостающую информацию о лицензиях
 
Общий порядок работы скрипта такой:
  1. Получаем список кластеров сервера RAS из таблицы ras_servers в базе Postre
  2. Получаем список информационных баз кластера
  3. Получаем список процессов кластера
  4. Получаем список сеансов и их лицензий
  5. Сводим все данные и заносим в целевую таблицу
 
Проверим, что у нас установлен 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\n' "$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
 
Сделаем отдельный график для лицензий, утилизированный сервером и клиентом :
--утилизировано серверных и клиентских
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
 
На выходе получаются вот такие прекрасные графики.
 
 
 
 
 
 

лицензии ras rac

См. также

Автоподбор ролей для профилей и групп доступа в любых типовых базах 1С УТ 11, КА 2, ERP2, Розница 2/3, УНФ 16/3, БП 3, ЗУП 3 и подобных (УФ, Платформа 8.3.14+)

Инструменты администратора БД Роли и права 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Роли… Вы тратите много времени и сил на подбор ролей среди около 2400 в ERP или 1500 в Рознице 2, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 15.12.2023, версия 1.1.

14400 руб.

06.12.2023    3528    19    1    

38

Infostart УДиФ: Управление данными и формами

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

10000 руб.

10.11.2023    4236    12    2    

36

SALE! %

PowerTools

Инструментарий разработчика Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

3600 2880 руб.

14.01.2013    178567    1083    0    

861

Ускоренное проведение документов (x4), устранение ошибок 60/62 счетов и зачет авансов (Бухгалтерия 3.0)

Закрытие периода Инструменты администратора БД Корректировка данных Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Расширение «Оперативное проведение» в 4 раза уменьшает время проведения документов и закрытия месяца. Является комплексным решением проблем 62 и 60 счетов. Оптимизирует проведение при включенной функциональной опции «Раздельный учет НДС». Используется в более 10 организациях уже 2 года. Совместимо с конфигурацией Бухгалтерия 3.0 (+КОРП).

14400 руб.

29.04.2020    27823    82    146    

60

Система хранения присоединенных файлов в томах на диске

Инструменты администратора БД Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление производственным предприятием Платные (руб)

Конфигурация Комплексная автоматизация 1.1 (и УПП 1.3 тоже) хранит файлы и изображения в справочнике Хранилище дополнительной информации в реквизите Хранилище типа ХранилищеЗначений. Та же история с ВложениямиЭлектроннойПочты. Но при этом присоединенные файлы в Электронном документообороте хранит в томах на диске. Эта доработка позволяет использовать стандартный механизм хранения файлов, изображений и вложений электронных писем в томах на диске. При этом можно разделить тома хранения по объектам конфигурации.

4200 руб.

10.11.2015    61510    89    59    

74

"Менеджер потоков 2.1": УПП: "Восстановление партий"

Инструменты администратора БД Платформа 1С v8.3 1С:Управление производственным предприятием Россия Бухгалтерский учет Управленческий учет Платные (руб)

Как оптимизировать то, что, считалось, не поддается оптимизации? Как повысить доступность базы данных? Как проводить самую «времяемкую» операцию не по паре раз в неделю, а по несколько раз в день*? Ответ есть!

20000 руб.

12.09.2019    11850    5    9    

7

Хранилище файлов на SQL

Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Управленческий учет Платные (руб)

Привязка файлов / сканов к объектам 1С с сохранением их на SQL-сервере

12000 руб.

09.10.2019    11151    5    8    

9

Конфигурация Session Monitor

Мониторинг Инструменты администратора БД Платформа 1С v8.3 Россия Платные (руб)

Конфигурация Session Monitor предназначена для мониторинга сервера 1С с целью отслеживания чрезмерной нагрузки от конкретных сеансов и скорости реакции рабочих процессов.

1500 руб.

01.12.2020    14370    33    0    

48
Комментарии
Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. asved.ru 36 03.12.18 07:55 Сейчас в теме
Весь процесс сбора данных есть в ЦКК. Немного его допиливаем, а логику аггрегации лицензий выносим в отчет. Или в алгоритм заполнения мониторинговой БД, если используется сторонняя система мониторинга. В частности, я шлю в Zabbix посредством ВК, реализующей Zabbix sender.
3. tvm 03.12.18 09:15 Сейчас в теме
(1) а зачем через ВК в Zabbix слать? Он может сам дергать агента и получать инфу
6. asved.ru 36 03.12.18 15:48 Сейчас в теме
(3) Так экономнее: агент сам по себе в 1С ходить не умеет, типовое решение - агент читает stdout дочернего процесса. Который еще нужно запустить, потратив на это системные ресурсы.
7. tvm 03.12.18 16:10 Сейчас в теме
(6) если агентом дергать rac- не сильно то и затратнее
2. Mortum 03.12.18 08:10 Сейчас в теме
Хороший, навороченный, но сложный велосипед.
kauksi; MrWonder; +2 Ответить
4. MrWonder 642 03.12.18 09:19 Сейчас в теме
(2) Спасибо за оценку. Я поэтому и описал подробно, чтобы самому всё уложить в голове )))
5. capitan 2470 03.12.18 14:06 Сейчас в теме
Может это и велосипед, не знаю.
Но велосипед боевой )
Как совет - по хорошему надо просто серверам ограничить доступ к аппаратным лицензиям.
Уберете путаницу и количество свободных лицензий увеличите
8. bforce 481 23.12.18 22:45 Сейчас в теме
У в качестве центра мониторинга - Zabbix. Он сразу избавляет вас от 2,4,5 пукнта. Плюс есть агент, который сам отправляет данные серверу.
Мониторинг "железных" лицензий прямо на хосте, где они установлены. Так честнее и проще.
Ну и графана для красоты (sql-запросы пилить не надо, так как есть интеграция с заббиксом, - достаточно выбрать показатель/item).
9. MrWonder 642 23.12.18 23:20 Сейчас в теме
(8) Мониторинг железных ключей - это хорошо. Но он работает у Вас только под Win.
И ещё - если выдаёте железные ключи сервером, то вы не знаете, сколько их выдано. Ибо эти данные не получить из ключа, увы.
Буду рад, если опровергните меня по любому из пунктов.
В конце хочу добавить, что данный мониторинг не ограничивается только лишь ключами ;)
О разнообразии применений собираемых данных, по мере накопления UseCases, напишу ещё одну статью.
10. bforce 481 24.12.18 23:16 Сейчас в теме
(9)
И ещё - если выдаёте железные ключи сервером, то вы не знаете, сколько их выдано. Ибо эти данные не получить из ключа, увы.
Буду рад, если опровергните меня по любому из пунктов.

Здесь у многих заблуждение. Да, в списке сессий будет видна только одна запись самого сервера 1С, но ключ же как-то понимает сколько ключей он раздал. Эта цифра (без детализации по хостам) видна и в аладдиновском мониторе, и может быть получена программно, используя dll-ку.

Но он работает у Вас только под Win.

Кросплатформенность сейчас, конечно, в моде, но не настолько, чтобы фанатично первым делом переходить на линукс. Впрочем, это Ваши предпочтения и требования.
Я за более взвешенный подход: использовать то, что лучше и удобнее для каждой конкретной задачи. Возможно, у Вас так, но из статьи этого не видно.

В конце хочу добавить, что данный мониторинг не ограничивается только лишь ключами ;)

Аналогично.
11. MrWonder 642 25.12.18 00:14 Сейчас в теме
(10)
Здесь у многих заблуждение. Да, в списке сессий будет видна только одна запись самого сервера 1С, но ключ же как-то понимает сколько ключей он раздал. Эта цифра (без детализации по хостам) видна и в аладдиновском мониторе, и может быть получена программно, используя dll-ку.


Либо я чего-то не знаю, либо Вы.
Я утверждаю (и мои слова подкреплены ответом из 1С) о том, что получить количество утилизированных СП 1С лицензий из аппаратного ключа средствами, в первую очередь, Alladdin Monitor, нельзя.
Можете показать как вы получаете количество выданных СП 1С лицензий из многопользовательского ключа HASP?

По поводу остальных выводов и заключений:
1. Для меня перспектива - кроссплатформенность. Делать сейчас одно, а потом переделывать в другое можно. Но это не мой выбор.
2. Расскажите о том, как сделано у Вас. Мне очень интересно.
12. bforce 481 02.01.19 23:18 Сейчас в теме
(11)
Я утверждаю (и мои слова подкреплены ответом из 1С) о том, что получить количество утилизированных СП 1С лицензий из аппаратного ключа средствами, в первую очередь, Alladdin Monitor, нельзя.

Конечно, оно так. Но нужно помнить один нюанс. Занятые лицензии не увидеть, если Ваш ключ воткнут непосредственно в сервер 1С. Тогда получение лицензии идет мимо службы HASP.
А, вот, если для ключа выделить отдельную машину (мы, например, по серверам СУБД распихали), то правильное количество лицензий начнет показывать даже Alladdin Monitor. Собственно, так используем и мониторим.

(11)
2. Расскажите о том, как сделано у Вас. Мне очень интересно.

Так я уже написал в первом посте. Zabbix используются для мониторинга железа, операционной системы, а мы туда еще простенькими PowerShell коммандлетами пропихиваем свои метрики бизнес-приложения.
Я тут америку не открыл и рекламировать это смысла не вижу. Это все равно что запилить статью, например, о том как здорово я установил платформу на 50+ пользовательских компьютеров при помощи простеньких команд.

Свои собственный решения хороши тем, что в них у Вас полная уверенность. Но передать другому специалисту их нельзя. Он их выбросит и напишет свои скрипты. На Заббикс в данном случае нужно смотреть как на универсальный и мощный инструмент, своего рода Платформа, которая уже из коробки может очень многое. Плюс всегда есть Агент, который сам выполнит скрипт и будет сообщать об ошибках. А если машина ушла в небытие, то о недоступности Агента сообщит уже Сервер. И, если не прикручивать к нему для красоты Графану, то одного Заббикса будет уже достаточно.
13. MrWonder 642 02.01.19 23:32 Сейчас в теме
(12)
Конечно, оно так. Но нужно помнить один нюанс. Занятые лицензии не увидеть, если Ваш ключ воткнут непосредственно в сервер 1С. Тогда получение лицензии идет мимо службы HASP.
А, вот, если для ключа выделить отдельную машину (мы, например, по серверам СУБД распихали), то правильное количество лицензий начнет показывать даже Alladdin Monitor. Собственно, так используем и мониторим.

Я знаю о трёх способах выдачи лицензий сервером приложений 1С:
1. Выдачи из ключа под сервером. Этот способ используется всегда первым. Есть ли служба nethasp, нет ли её, СП 1С всегда начинает выдавать лицензии из ключа под собой.
2. Программные лицензии. Здесь всё просто и очевидно. Нечего и добавить.
3. Лицензии из сетевого ключа (прописанного в nethasp.ini). И вот здесь, увы, Alladdin Monitor бессилен. Он показывает корректно только лицензии, полученные клиентом. А лицензии, выданные СП 1С он не покажет верно. Можете проверить. Это так. И 1С это подтверждает.

А если машина ушла в небытие, то о недоступности Агента сообщит уже Сервер. И, если не прикручивать к нему для красоты Графану, то одного Заббикса будет уже достаточно.

Zabbix я тоже использую. Но не для метрик работы 2000 сеансов. Это чрезвычайно избыточно - хранить все эти данные в Zabbix. Совершенство в многообразии.
14. bforce 481 03.01.19 10:03 Сейчас в теме
(13)
Можете проверить. Это так. И 1С это подтверждает.

Все уже проверено до Вас. Просто Вы неверно поняли то, что написала 1С и корректировать свою точку зрения не хотите.
Прикрепленные файлы:
15. MrWonder 642 03.01.19 14:12 Сейчас в теме
(14) То, что Вы видите соединения от сервера в ключе, не значит, что Вы видите количество утилизированных ключей ))
И да, я действительно не хочу корректировать свою точку зрения. Просто потому, что я проверял внимательней - сравнивал количество записей в Alladdin Monitor с количеством лицензий, утилизированных в консоли администрирования.
Мдаа, а ещё с Вашей стороны в высшей степени неразумно делать выводы о понимании мною письма, содержимого которого Вы даже не знаете. Ну что ж, давайте посмотрим вместе:

Если захотите проверить нормально, а не на отъ...сь, то пишите, если посчитаете нужным.
Удачи с математикой ;)
user774630; +1 1 Ответить
16. user1417606 25.02.21 16:50 Сейчас в теме
скрипт отрабатывает все данные получает но не заносит в базу
fields =re.findall(r'session\s+\:(.+)\r*\nsession-id\s+\:(.+)\r*\ninfobase\s+\:(.+)\nconnection.*\nprocess\s+\:(.+)\nuser-name\s+\:(.+)\nhost\s+\:(.+)\napp-id\s+\:(.+)\nlocale.*\nstarted-at\s+\........ возвращает пустой массив
Есть мысли что поправить?
17. ielijah 17.05.22 15:59 Сейчас в теме
duration-current-dbms
RAC возвращает duration current-dbms без первого тире
Я надеюсь это обходится в скрипте
18. DrSender 82 28.07.23 16:48 Сейчас в теме
Отличная работа! Возможно станет намного актуальнее в процессах импортозамещения.

Использую похожие механизмы, складываю все собранное (в т.числе ключи) планами SQL и приложением 1C в базу MS SQL и отображаю Графаной.
Для меня намного проще, нагляднее и гибче , чем Zabbix .
Оставьте свое сообщение