registry_log.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "daemon/common.h"
  3. #include "registry_internals.h"
  4. void registry_log(char action, REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *u, const char *name) {
  5. if(likely(registry.log_fp)) {
  6. if(unlikely(fprintf(registry.log_fp, "%c\t%08x\t%s\t%s\t%s\t%s\n",
  7. action,
  8. p->last_t,
  9. p->guid,
  10. m->guid,
  11. name,
  12. string2str(u)) < 0))
  13. netdata_log_error("Registry: failed to save log. Registry data may be lost in case of abnormal restart.");
  14. // we increase the counter even on failures
  15. // so that the registry will be saved periodically
  16. registry.log_count++;
  17. // this must be outside the log_lock(), or a deadlock will happen.
  18. // registry_db_save() checks the same inside the log_lock, so only
  19. // one thread will save the db
  20. if(unlikely(registry_db_should_be_saved()))
  21. registry_db_save();
  22. }
  23. }
  24. int registry_log_open(void) {
  25. if(registry.log_fp)
  26. fclose(registry.log_fp);
  27. registry.log_fp = fopen(registry.log_filename, "a");
  28. if(registry.log_fp) {
  29. if (setvbuf(registry.log_fp, NULL, _IOLBF, 0) != 0)
  30. netdata_log_error("Cannot set line buffering on registry log file.");
  31. return 0;
  32. }
  33. netdata_log_error("Cannot open registry log file '%s'. Registry data will be lost in case of netdata or server crash.", registry.log_filename);
  34. return -1;
  35. }
  36. void registry_log_close(void) {
  37. if(registry.log_fp) {
  38. fclose(registry.log_fp);
  39. registry.log_fp = NULL;
  40. }
  41. }
  42. void registry_log_recreate(void) {
  43. if(registry.log_fp != NULL) {
  44. registry_log_close();
  45. // open it with truncate
  46. registry.log_fp = fopen(registry.log_filename, "w");
  47. if(registry.log_fp) fclose(registry.log_fp);
  48. else
  49. netdata_log_error("Cannot truncate registry log '%s'", registry.log_filename);
  50. registry.log_fp = NULL;
  51. registry_log_open();
  52. }
  53. }
  54. ssize_t registry_log_load(void) {
  55. ssize_t line = -1;
  56. // closing the log is required here
  57. // otherwise we will append to it the values we read
  58. registry_log_close();
  59. netdata_log_debug(D_REGISTRY, "Registry: loading active db from: %s", registry.log_filename);
  60. FILE *fp = fopen(registry.log_filename, "r");
  61. if(!fp)
  62. netdata_log_error("Registry: cannot open registry file: %s", registry.log_filename);
  63. else {
  64. char *s, buf[4096 + 1];
  65. line = 0;
  66. size_t len = 0;
  67. while ((s = fgets_trim_len(buf, 4096, fp, &len))) {
  68. line++;
  69. switch (s[0]) {
  70. case 'A': // accesses
  71. case 'D': // deletes
  72. // verify it is valid
  73. if (unlikely(len < 85 || s[1] != '\t' || s[10] != '\t' || s[47] != '\t' || s[84] != '\t')) {
  74. netdata_log_error("Registry: log line %zd is wrong (len = %zu).", line, len);
  75. continue;
  76. }
  77. s[1] = s[10] = s[47] = s[84] = '\0';
  78. // get the variables
  79. time_t when = (time_t)strtoul(&s[2], NULL, 16);
  80. char *person_guid = &s[11];
  81. char *machine_guid = &s[48];
  82. char *name = &s[85];
  83. // skip the name to find the url
  84. char *url = name;
  85. while(*url && *url != '\t') url++;
  86. if(!*url) {
  87. netdata_log_error("Registry: log line %zd does not have a url.", line);
  88. continue;
  89. }
  90. *url++ = '\0';
  91. // make sure the person exists
  92. // without this, a new person guid will be created
  93. REGISTRY_PERSON *p = registry_person_find(person_guid);
  94. if(!p) p = registry_person_allocate(person_guid, when);
  95. if(s[0] == 'A')
  96. registry_request_access(p->guid, machine_guid, url, name, when);
  97. else
  98. registry_request_delete(p->guid, machine_guid, url, name, when);
  99. registry.log_count++;
  100. break;
  101. default:
  102. netdata_log_error("Registry: ignoring line %zd of filename '%s': %s.", line, registry.log_filename, s);
  103. break;
  104. }
  105. }
  106. fclose(fp);
  107. }
  108. // open the log again
  109. registry_log_open();
  110. return line;
  111. }