page_module.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // package page_module -- страница показа модуля.
  2. package page_module
  3. import (
  4. _ "embed"
  5. "fmt"
  6. "strings"
  7. "github.com/gofiber/fiber/v3"
  8. mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev1/comp_spec"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx"
  11. "gitp78su.ipnodns.ru/svi/kern/v4/lev2/kspec"
  12. "gitp78su.ipnodns.ru/svi/kern/v4/lev3/mod_ent/mod_num"
  13. "gitp78su.ipnodns.ru/svi/kern/v4/lev3/mod_spec"
  14. )
  15. // PageModule -- страница показа модуля.
  16. type PageModule struct {
  17. ctx kspec.IKernelCtx
  18. }
  19. var page *PageModule
  20. // GetPageModule -- возвращает страницу модуля.
  21. func GetPageModule() mL0.IResult[*PageModule] {
  22. if page != nil {
  23. return mL0.NewOk(page)
  24. }
  25. kCtx := kctx.GetKernelCtx()
  26. optFiber := kCtx.Get("fiberApp")
  27. if optFiber.IsNone() {
  28. err := fmt.Errorf("GetPageModule(): not found fiberApp in kernel ctx")
  29. return mL0.NewErr[*PageModule](err)
  30. }
  31. fiberApp := optFiber.Some().Val().(*fiber.App)
  32. kCtx.Set("fiberApp", fiberApp, "fiberApp in GetPageModule()")
  33. sf := &PageModule{
  34. ctx: kCtx,
  35. }
  36. fiberApp.Post("/module/:id", sf.postModule)
  37. fiberApp.Post("/module_state/:id", sf.postModuleState)
  38. fiberApp.Post("/module_ctx/:id", sf.postModuleCtx)
  39. fiberApp.Post("/module_log/:id", sf.postModuleLog)
  40. fiberApp.Post("/module_svg_sec/svg_sec_:id.svg", sf.postSvgSec)
  41. fiberApp.Post("/module_svg_min/svg_min_:id.svg", sf.postSvgMin)
  42. fiberApp.Post("/module_svg_day/svg_day_:id.svg", sf.postSvgDay)
  43. page = sf
  44. return mL0.NewOk(sf)
  45. }
  46. //go:embed log_block.html
  47. var strLogBlock string
  48. // Возвращает страницу лога модуля.
  49. func (sf *PageModule) postModuleLog(ctx fiber.Ctx) error {
  50. _modNum := ctx.Params("id", "1")
  51. resNum := mod_num.FromStr(_modNum)
  52. if resNum.IsErr() {
  53. return ctx.SendString(resNum.Err().Error())
  54. }
  55. modNum := resNum.Ok()
  56. module, _ := sf.getModule(modNum)
  57. if module == nil {
  58. strOut := strings.ReplaceAll(strLogBlock, "{.id}", modNum.String())
  59. strOut = strings.ReplaceAll(strOut, "{.log}", strOut)
  60. strOut = strings.ReplaceAll(strOut, "{.name}", "not found")
  61. strOut = strings.ReplaceAll(strOut, "{.mod_state}", "")
  62. return ctx.SendString(strOut)
  63. }
  64. _log := module.Log()
  65. if module.Name().Get() == "kCtx" {
  66. _log = sf.ctx.Log()
  67. }
  68. strOut := ""
  69. for i := range 100 {
  70. msg := _log.Get(i).String()
  71. if strings.Contains(msg, "*no msg*") {
  72. continue
  73. }
  74. strOut += msg + "\n"
  75. }
  76. strOut = strings.ReplaceAll(strLogBlock, "{.log}", strOut)
  77. strOut = strings.ReplaceAll(strOut, "{.name}", module.Name().String())
  78. strOut = strings.ReplaceAll(strOut, "{.id}", _modNum)
  79. return ctx.SendString(strOut)
  80. }
  81. //go:embed ctx_row_val.html
  82. var strCtxRowVal string
  83. //go:embed ctx_row_block.html
  84. var strCtxRowBlock string
  85. // Возвращает блок контекста монолита.
  86. func (sf *PageModule) postModuleCtx(ctx fiber.Ctx) error {
  87. _modNum := ctx.Params("id", "1")
  88. resNum := mod_num.FromStr(_modNum)
  89. if resNum.IsErr() {
  90. err := fmt.Errorf("PageModule.postModuleCtx(): in extract module num(%q), err=\n\t%w",
  91. _modNum, resNum.Err())
  92. return err
  93. }
  94. modNum := resNum.Ok()
  95. module, _ := sf.getModule(modNum)
  96. if module == nil {
  97. strOut := strings.ReplaceAll(strCtxRowBlock, "{.id}", modNum.String())
  98. strOut = strings.ReplaceAll(strOut, "{.name}", "not found")
  99. strOut = strings.ReplaceAll(strOut, "{.ctx_block}", "")
  100. return ctx.SendString(strOut)
  101. }
  102. mCtx := module.Ctx()
  103. lst := mCtx.SortedList()
  104. if module.Name().Get() == "kCtx" {
  105. lst = sf.ctx.SortedList()
  106. }
  107. strOut := ""
  108. for _, val := range lst {
  109. strRow := strCtxRowVal
  110. strRow = strings.ReplaceAll(strRow, "{.key}", val.Key())
  111. _val := val.Val()
  112. valShort := fmt.Sprint(_val)
  113. runes := []rune(valShort)
  114. if len(runes) > 20 {
  115. runes = runes[:20]
  116. valShort = string(runes)
  117. }
  118. strRow = strings.ReplaceAll(strRow, "{.value}", valShort)
  119. _type := fmt.Sprintf("%#T", _val)
  120. _type = strings.ReplaceAll(_type, ".", ".<br>")
  121. strRow = strings.ReplaceAll(strRow, "{.type}", _type)
  122. strRow = strings.ReplaceAll(strRow, "{.createAt}", val.CreateAt().String())
  123. strRow = strings.ReplaceAll(strRow, "{.updateAt}", val.UpdateAt().String())
  124. strRow = strings.ReplaceAll(strRow, "{.comment}", val.Comment())
  125. strOut += strRow
  126. }
  127. strOut = strings.ReplaceAll(strCtxRowBlock, "{.ctx_block}", strOut)
  128. strOut = strings.ReplaceAll(strOut, "{.id}", modNum.String())
  129. strOut = strings.ReplaceAll(strOut, "{.name}", module.Name().String())
  130. return ctx.SendString(strOut)
  131. }
  132. //go:embed module_state.html
  133. var strStateModule string
  134. //go:embed module_state_block.html
  135. var strStateModuleBlock string
  136. // Показывает состояние модуля.
  137. func (sf *PageModule) postModuleState(ctx fiber.Ctx) error {
  138. _modNum := ctx.Params("id", "1")
  139. resNum := mod_num.FromStr(_modNum)
  140. if resNum.IsErr() {
  141. err := fmt.Errorf("PageModule.postModuleState(): in extract module num(%q), err=\n\t%w",
  142. _modNum, resNum.Err())
  143. return err
  144. }
  145. modNum := resNum.Ok()
  146. module, modVal := sf.getModule(modNum)
  147. if module == nil {
  148. strOut := strings.ReplaceAll(strStateModuleBlock, "{.id}", "")
  149. return ctx.SendString(strOut)
  150. }
  151. dictState := map[string]any{}
  152. dictState["{.name}"] = module.Name()
  153. dictState["{.createAt}"] = modVal.CreateAt()
  154. dictState["{.updateAt}"] = modVal.UpdateAt()
  155. dictState["{.comment}"] = modVal.Comment()
  156. dictState["{.id}"] = modNum.String()
  157. dictState["{.live}"] = module.Live()
  158. dictState["{.svg_sec}"] = module.Stat().SvgSec()
  159. strOut := strStateModuleBlock
  160. for key, val := range dictState {
  161. strOut = strings.ReplaceAll(strOut, key, fmt.Sprint(val))
  162. }
  163. return ctx.SendString(strOut)
  164. }
  165. // Показывает состояние модуля.
  166. func (sf *PageModule) postModule(ctx fiber.Ctx) error {
  167. _modNum := ctx.Params("id", "1")
  168. resNum := mod_num.FromStr(_modNum)
  169. if resNum.IsErr() {
  170. err := fmt.Errorf("PageModule.postModule(): in extract module num(%q), err=\n\t%w",
  171. _modNum, resNum.Err())
  172. return err
  173. }
  174. modNum := resNum.Ok()
  175. module, modVal := sf.getModule(modNum)
  176. if module == nil {
  177. strOut := strings.ReplaceAll(strStateModule, "{.name}", "unknown")
  178. strOut = strings.ReplaceAll(strOut, "{.mod_state}", "")
  179. strOut = strings.ReplaceAll(strOut, "{.id}", "")
  180. return ctx.SendString(strOut)
  181. }
  182. dictState := map[string]any{}
  183. dictState["{.name}"] = module.Name()
  184. dictState["{.createAt}"] = modVal.CreateAt()
  185. dictState["{.updateAt}"] = modVal.UpdateAt()
  186. dictState["{.comment}"] = modVal.Comment()
  187. // dictState["{.id}"] = id
  188. dictState["{.live}"] = module.Live()
  189. dictState["{.svg_sec}"] = module.Stat().SvgSec()
  190. strOut := strStateModuleBlock
  191. for key, val := range dictState {
  192. strOut = strings.ReplaceAll(strOut, key, fmt.Sprint(val))
  193. }
  194. {
  195. strOut = strings.ReplaceAll(strStateModule, "{.mod_state}", strOut)
  196. strOut = strings.ReplaceAll(strOut, "{.name}", module.Name().String())
  197. strOut = strings.ReplaceAll(strOut, "{.id}", modNum.String())
  198. }
  199. return ctx.SendString(strOut)
  200. }
  201. // Возвращает секундную статистику модуля.
  202. func (sf *PageModule) postSvgDay(ctx fiber.Ctx) error {
  203. _modNum := ctx.Params("id", "1")
  204. resNum := mod_num.FromStr(_modNum)
  205. if resNum.IsErr() {
  206. err := fmt.Errorf("PageModule.postSvgDay(): in extract module num(%q), err=\n\t%w",
  207. _modNum, resNum.Err())
  208. return err
  209. }
  210. modNum := resNum.Ok()
  211. module, _ := sf.getModule(modNum)
  212. if module == nil {
  213. return ctx.SendString("")
  214. }
  215. strSvgSec := module.Stat().SvgDay()
  216. ctx.Set("Content-Type", "image/svg+xml")
  217. return ctx.SendString(strSvgSec)
  218. }
  219. // Возвращает секундную статистику модуля.
  220. func (sf *PageModule) postSvgMin(ctx fiber.Ctx) error {
  221. _modNum := ctx.Params("id", "1")
  222. resNum := mod_num.FromStr(_modNum)
  223. if resNum.IsErr() {
  224. err := fmt.Errorf("PageModule.postSvgMin(): in extract module num(%q), err=\n\t%w",
  225. _modNum, resNum.Err())
  226. return err
  227. }
  228. modNum := resNum.Ok()
  229. module, _ := sf.getModule(modNum)
  230. if module == nil {
  231. return ctx.SendString("")
  232. }
  233. strSvgSec := module.Stat().SvgMin()
  234. ctx.Set("Content-Type", "image/svg+xml")
  235. return ctx.SendString(strSvgSec)
  236. }
  237. // Возвращает секундную статистику модуля.
  238. func (sf *PageModule) postSvgSec(ctx fiber.Ctx) error {
  239. _modNum := ctx.Params("id", "1")
  240. resNum := mod_num.FromStr(_modNum)
  241. if resNum.IsErr() {
  242. err := fmt.Errorf("PageModule.postSvgSec(): in extract module num(%q), err=\n\t%w",
  243. _modNum, resNum.Err())
  244. return err
  245. }
  246. modNum := resNum.Ok()
  247. module, _ := sf.getModule(modNum)
  248. if module == nil {
  249. return ctx.SendString("")
  250. }
  251. strSvgSec := module.Stat().SvgSec()
  252. ctx.Set("Content-Type", "image/svg+xml")
  253. return ctx.SendString(strSvgSec)
  254. }
  255. // Возвращает модуль.
  256. func (sf *PageModule) getModule(modNum mod_num.IModNumFix) (mod_spec.IKernelModule, comp_spec.ICtxValue) {
  257. optMonolit := sf.ctx.Get("monolit")
  258. if optMonolit.IsNone() {
  259. return nil, nil
  260. }
  261. mon := optMonolit.Some().Val().(mod_spec.IKernelMonolit)
  262. chLst := mon.Ctx().SortedList()
  263. var (
  264. val comp_spec.ICtxValue
  265. isFind bool
  266. )
  267. for _, val = range chLst {
  268. name := "module_" + modNum.String()
  269. if name == val.Key() {
  270. isFind = true
  271. break
  272. }
  273. }
  274. if !isFind {
  275. return nil, nil
  276. }
  277. mod := val.Val().(mod_spec.IKernelModule)
  278. return mod, val
  279. }