대시보드 새 게시글 통계 오류

root@prometheus-discourse-sidemount:/var/www/discourse# rails c
Plugin name is 'discourse-docs', but plugin directory is named 'discourse-knowledge-explorer'
Plugin name is 'discourse-user-notes', but plugin directory is named 'discourse-staff-notes'
Loading production environment (Rails 7.2.2.1)
discourse(prod)> Post.public_posts_count_per_day(4.weeks.ago, Time.zone.now)
=> {}
discourse(prod)>

많이 사용합니다… :wink: 컨테이너 설정 yaml에서 가져온 것입니다:

https://github.com/discourse/docker_manager.git
https://github.com/discourse/discourse-adplugin.git
https://github.com/discourse/discourse-affiliate.git
https://github.com/discourse/discourse-ai.git
https://github.com/discourse/discourse-akismet.git
https://github.com/pfaffman/discourse-allow-pm-to-staff.git
https://github.com/discourse/discourse-animated-avatars.git
https://github.com/discourse/discourse-apple-auth.git
https://github.com/discourse/discourse-assign.git
https://github.com/discourse/discourse-authentication-validations.git
https://github.com/discourse/discourse-auto-deactivate.git
https://github.com/discourse/discourse-bbcode.git
https://github.com/discourse/discourse-bcc.git
https://github.com/discourse/discourse-cakeday.git
https://github.com/discourse/discourse-calendar.git
https://github.com/discourse/discourse-characters-required.git
https://github.com/discourse/discourse-chat-integration.git
https://github.com/discourse/discourse-data-explorer.git
https://github.com/discourse/discourse-fingerprint.git
https://github.com/discourse/discourse-follow.git
https://github.com/leodavidson/discourse-forcemoderation.git
https://github.com/discourse/discourse-gamification.git
https://github.com/discourse/discourse-hcaptcha.git
https://github.com/discourse/discourse-knowledge-explorer.git
https://github.com/angusmcleod/discourse-locations.git
https://github.com/discourse/discourse-login-with-amazon.git
https://github.com/discourse/discourse-math.git
https://github.com/discourse/discourse-microsoft-auth.git
https://github.com/discoursehosting/discourse-migratepassword.git
https://github.com/discourse/discourse-policy.git
https://github.com/paviliondev/discourse-post-badges-plugin.git
https://github.com/discourse/discourse-post-voting.git
https://github.com/communiteq/discourse-private-topics.git
https://github.com/discourse/discourse-push-notifications.git
https://github.com/featheredtoast/discourse-pushover-notifications.git
https://github.com/paviliondev/discourse-ratings.git
https://github.com/discourse/discourse-reactions.git
https://github.com/discourse/discourse-restricted-replies.git
https://github.com/discourse/discourse-saved-searches.git
https://github.com/discourse/discourse-shared-edits.git
https://github.com/discourse/discourse-signatures.git
https://github.com/discourse/discourse-solved.git
https://github.com/discourse/discourse-staff-alias.git
https://github.com/discourse/discourse-staff-notes.git
https://github.com/discourse/discourse-steam-login.git
https://github.com/singerscreations/discourse-stopforumspam.git
https://github.com/discourse/discourse-styleguide.git
https://github.com/discourse/discourse-subscriptions.git
https://github.com/davidtaylorhq/discourse-telegram-notifications.git
https://github.com/discourse/discourse-templates.git
https://github.com/discourse/discourse-tooltips.git
https://github.com/jannolii/discourse-topic-trade-buttons.git
https://github.com/discourse/discourse-topic-voting.git
https://github.com/discourse/discourse-translator.git
https://github.com/discourse/discourse-user-field-prompt.git
https://github.com/discourse/discourse-whos-online.git
https://github.com/discourse/discourse-yearly-review.git

참고로, @qingfeng1024 님도 이 문제를 경험하고 있으므로, 이것은 개인적인 문제가 아닌 것 같습니다. 그분이 위 테스트가 해당 포럼에서 어떤 결과를 보여주는지, 그리고 어떤 플러그인을 사용 중인지도 알려줄 수 있으면 좋겠습니다.

2개의 좋아요

@martin 이 문제에 대해 혹시 아이디어가 있나요?

1개의 좋아요

아니요, 죄송합니다. 이 문제가 좀 놓쳐져서요.

@qingfeng1024 rails 콘솔에서 다음을 실행하면 정확히 동일한 현상이 발생합니까?

MethodProfiler.output_sql_to_stderr!
Report.find("posts", start_date: 4.weeks.ago, end_date: Time.zone.now).data

이 게시글과 같은 출력이 표시될 것입니다. 여기에 복사해서 붙여넣을 수 있을까요? Dashboard New Posts statistics broken - #18 by Roi

@kris.kotlarek 여기서 아직 해결책을 찾지 못했습니다. 이 주제에서 눈에 띄는 부분이 있는지 확인해 주실 수 있을까요?

2개의 좋아요
root@shannon-20250121-app:/var/www/discourse# rails c
Plugin name is 'DiscourseMatheditor', but plugin directory is named 'discourse-matheditor'
Loading production environment (Rails 7.2.2.1)



discourse(prod)> MethodProfiler.output_sql_to_stderr!
Stop! This instrumentation is not intended for use in production outside of debugging scenarios. Please be sure you know what you are doing when enabling this instrumentation.
=> true




discourse(prod)> Report.find("posts", start_date: 4.weeks.ago, end_date: Time.zone.now).data
debugsql (sql): SET client_min_messages TO 'warning'
debugsql (sec): 0.0
debugsql (sql): SET standard_conforming_strings = on
debugsql (sec): 0.0
debugsql (sql): SET intervalstyle = iso_8601
debugsql (sec): 0.0
debugsql (sql): SELECT t.oid, t.typname
FROM pg_type as t
WHERE t.typname IN ('int2', 'int4', 'int8', 'oid', 'float4', 'float8', 'numeric', 'bool', 'timestamp', 'timestamptz', 'date')
debugsql (sec): 0.001
debugsql (sql): SET SESSION timezone TO 'UTC'
debugsql (sec): 0.0
debugsql (sql): SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
FROM pg_type as t
LEFT JOIN pg_range as r ON oid = rngtypid
WHERE
  t.typname IN ('int2', 'int4', 'int8', 'oid', 'float4', 'float8', 'text', 'varchar', 'char', 'name', 'bpchar', 'bool', 'bit', 'varbit', 'date', 'money', 'bytea', 'point', 'hstore', 'json', 'jsonb', 'cidr', 'inet', 'uuid', 'xml', 'tsvector', 'macaddr', 'citext', 'ltree', 'line', 'lseg', 'box', 'path', 'polygon', 'circle', 'numeric', 'interval', 'time', 'timestamp', 'timestamptz')
debugsql (sec): 0.002
debugsql (sql): SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
FROM pg_type as t
LEFT JOIN pg_range as r ON oid = rngtypid
WHERE
  t.typtype IN ('r', 'e', 'd')
debugsql (sec): 0.001
debugsql (sql): SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
FROM pg_type as t
LEFT JOIN pg_range as r ON oid = rngtypid
WHERE
  t.typelem IN (16, 17, 18, 19, 20, 21, 23, 25, 26, 114, 142, 600, 601, 602, 603, 604, 628, 700, 701, 718, 790, 829, 869, 650, 1042, 1043, 1082, 1083, 1114, 1184, 1186, 1560, 1562, 1700, 2950, 3614, 3802, 16924, 88307, 88314, 106343, 106350, 13223, 13226, 13228, 13234, 13236, 3904, 3906, 3908, 3910, 3912, 3926)
debugsql (sec): 0.001
debugsql (sql): SELECT a.attname, format_type(a.atttypid, a.atttypmod),
       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
       c.collname, col_description(a.attrelid, a.attnum) AS comment,
       attidentity AS identity,
       attgenerated as attgenerated
  FROM pg_attribute a
  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
  LEFT JOIN pg_type t ON a.atttypid = t.oid
  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
 WHERE a.attrelid = '"themes"'::regclass
   AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum
debugsql (sec): 0.002
debugsql (sql): SHOW max_identifier_length
debugsql (sec): 0.0
debugsql (sql): ;
debugsql (sec): 0.0
debugsql (sql): SELECT a.attname
  FROM (
         SELECT indrelid, indkey, generate_subscripts(indkey, 1) idx
           FROM pg_index
          WHERE indrelid = '"themes"'::regclass
            AND indisprimary
       ) i
  JOIN pg_attribute a
    ON a.attrelid = i.indrelid
   AND a.attnum = i.indkey[i.idx]
 ORDER BY i.idx
debugsql (sec): 0.008
debugsql (sql): SELECT "themes".* FROM "themes" WHERE "themes"."id" = 2 ORDER BY "themes"."id" ASC LIMIT 1
debugsql (sec): 0.0
debugsql (sql): ;
debugsql (sec): 0.0
debugsql (sql): SELECT a.attname
  FROM (
         SELECT indrelid, indkey, generate_subscripts(indkey, 1) idx
           FROM pg_index
          WHERE indrelid = '"color_schemes"'::regclass
            AND indisprimary
       ) i
  JOIN pg_attribute a
    ON a.attrelid = i.indrelid
   AND a.attnum = i.indkey[i.idx]
 ORDER BY i.idx
debugsql (sec): 0.008
debugsql (sql): ;
debugsql (sec): 0.0
debugsql (sql): SELECT a.attname, format_type(a.atttypid, a.atttypmod),
       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
       c.collname, col_description(a.attrelid, a.attnum) AS comment,
       attidentity AS identity,
       attgenerated as attgenerated
  FROM pg_attribute a
  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
  LEFT JOIN pg_type t ON a.atttypid = t.oid
  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
 WHERE a.attrelid = '"color_schemes"'::regclass
   AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum
debugsql (sec): 0.001
debugsql (sql): ;
debugsql (sec): 0.0
debugsql (sql): SELECT "color_schemes".* FROM "color_schemes" WHERE (color_schemes.id NOT IN (SELECT color_scheme_id FROM theme_color_schemes)) AND "color_schemes"."id" = 5 LIMIT 1
debugsql (sec): 0.001
debugsql (sql): ;
debugsql (sec): 0.0
debugsql (sql): SELECT a.attname
  FROM (
         SELECT indrelid, indkey, generate_subscripts(indkey, 1) idx
           FROM pg_index
          WHERE indrelid = '"color_scheme_colors"'::regclass
            AND indisprimary
       ) i
  JOIN pg_attribute a
    ON a.attrelid = i.indrelid
   AND a.attnum = i.indkey[i.idx]
 ORDER BY i.idx
debugsql (sec): 0.008
debugsql (sql): ;
debugsql (sec): 0.0
debugsql (sql): SELECT a.attname, format_type(a.atttypid, a.atttypmod),
       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
       c.collname, col_description(a.attrelid, a.attnum) AS comment,
       attidentity AS identity,
       attgenerated as attgenerated
  FROM pg_attribute a
  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
  LEFT JOIN pg_type t ON a.atttypid = t.oid
  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
 WHERE a.attrelid = '"color_scheme_colors"'::regclass
   AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum
debugsql (sec): 0.001
debugsql (sql): ;
debugsql (sec): 0.0
debugsql (sql): SELECT "color_scheme_colors".* FROM "color_scheme_colors" WHERE "color_scheme_colors"."color_scheme_id" = 5 ORDER BY id ASC
debugsql (sec): 0.001
debugsql (sql): BEGIN
debugsql (sec): 0.0
debugsql (sql): SET TRANSACTION READ ONLY
debugsql (sec): 0.002
debugsql (sql): SET LOCAL statement_timeout = 20000
debugsql (sec): 0.0
debugsql (sql): SELECT a.attname, format_type(a.atttypid, a.atttypmod),
       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
       c.collname, col_description(a.attrelid, a.attnum) AS comment,
       attidentity AS identity,
       attgenerated as attgenerated
  FROM pg_attribute a
  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
  LEFT JOIN pg_type t ON a.atttypid = t.oid
  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
 WHERE a.attrelid = '"posts"'::regclass
   AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum
debugsql (sql): SET client_min_messages TO 'warning'
debugsql (sec): 0.0
debugsql (sql): SET standard_conforming_strings = on
debugsql (sec): 0.0
debugsql (sql): SET intervalstyle = iso_8601
debugsql (sec): 0.0
debugsql (sql): SELECT t.oid, t.typname
FROM pg_type as t
WHERE t.typname IN ('int2', 'int4', 'int8', 'oid', 'float4', 'float8', 'numeric', 'bool', 'timestamp', 'timestamptz', 'date')
debugsql (sec): 0.003
debugsql (sql): SELECT a.attname, format_type(a.atttypid, a.atttypmod),
       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
       c.collname, col_description(a.attrelid, a.attnum) AS comment,
       attidentity AS identity,
       attgenerated as attgenerated
  FROM pg_attribute a
  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
  LEFT JOIN pg_type t ON a.atttypid = t.oid
  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
 WHERE a.attrelid = '"category_custom_fields"'::regclass
   AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum
debugsql (sec): 0.005
debugsql (sql): SET SESSION timezone TO 'UTC'
debugsql (sec): 0.001
debugsql (sql): SELECT "category_custom_fields"."category_id" FROM "category_custom_fields" WHERE "category_custom_fields"."name" = 'private_topics_enabled'
debugsql (sec): 0.001
debugsql (sql): SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
FROM pg_type as t
LEFT JOIN pg_range as r ON oid = rngtypid
WHERE
  t.typname IN ('int2', 'int4', 'int8', 'oid', 'float4', 'float8', 'text', 'varchar', 'char', 'name', 'bpchar', 'bool', 'bit', 'varbit', 'date', 'money', 'bytea', 'point', 'hstore', 'json', 'jsonb', 'cidr', 'inet', 'uuid', 'xml', 'tsvector', 'macaddr', 'citext', 'ltree', 'line', 'lseg', 'box', 'path', 'polygon', 'circle', 'numeric', 'interval', 'time', 'timestamp', 'timestamptz')
debugsql (sec): 0.001
debugsql (sql): SELECT a.attname
  FROM (
         SELECT indrelid, indkey, generate_subscripts(indkey, 1) idx
           FROM pg_index
          WHERE indrelid = '"topics"'::regclass
            AND indisprimary
       ) i
  JOIN pg_attribute a
    ON a.attrelid = i.indrelid
   AND a.attnum = i.indkey[i.idx]
 ORDER BY i.idx
debugsql (sec): 0.002
debugsql (sql): SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
FROM pg_type as t
LEFT JOIN pg_range as r ON oid = rngtypid
WHERE
  t.typtype IN ('r', 'e', 'd')
debugsql (sec): 0.001
debugsql (sql): SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
FROM pg_type as t
LEFT JOIN pg_range as r ON oid = rngtypid
WHERE
  t.typelem IN (16, 17, 18, 19, 20, 21, 23, 25, 26, 114, 142, 600, 601, 602, 603, 604, 628, 700, 701, 718, 790, 829, 869, 650, 1042, 1043, 1082, 1083, 1114, 1184, 1186, 1560, 1562, 1700, 2950, 3614, 3802, 16924, 88307, 88314, 106343, 106350, 13223, 13226, 13228, 13234, 13236, 3904, 3906, 3908, 3910, 3912, 3926)
debugsql (sec): 0.001
debugsql (sec): 0.009
debugsql (sql): SELECT a.attname
  FROM (
         SELECT indrelid, indkey, generate_subscripts(indkey, 1) idx
           FROM pg_index
          WHERE indrelid = '"posts"'::regclass
            AND indisprimary
       ) i
  JOIN pg_attribute a
    ON a.attrelid = i.indrelid
   AND a.attnum = i.indkey[i.idx]
 ORDER BY i.idx
debugsql (sec): 0.007
debugsql (sql): SELECT a.attname, format_type(a.atttypid, a.atttypmod),
       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
       c.collname, col_description(a.attrelid, a.attnum) AS comment,
       attidentity AS identity,
       attgenerated as attgenerated
  FROM pg_attribute a
  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
  LEFT JOIN pg_type t ON a.atttypid = t.oid
  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
 WHERE a.attrelid = '"topics"'::regclass
   AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum
debugsql (sec): 0.002
debugsql (sql): SELECT COUNT(*) AS "count_all", date(posts.created_at) AS "date_posts_created_at" FROM "posts" INNER JOIN "topics" ON "topics"."deleted_at" IS NULL AND "topics"."id" = "posts"."topic_id" WHERE "posts"."deleted_at" IS NULL AND (topics.archetype <> 'private_message') AND NOT ((topics.category_id IN (NULL))) AND (posts.created_at >= '2025-03-03 06:42:19.865947' AND posts.created_at <= '2025-03-31 06:42:19.866261') AND "posts"."post_type" = 1 GROUP BY date(posts.created_at) ORDER BY date(posts.created_at)
debugsql (sec): 0.002
debugsql (sql): SELECT "category_custom_fields"."category_id" FROM "category_custom_fields" WHERE "category_custom_fields"."name" = 'private_topics_enabled'
debugsql (sec): 0.0
debugsql (sql): SELECT COUNT(*) FROM "posts" INNER JOIN "topics" ON "topics"."deleted_at" IS NULL AND "topics"."id" = "posts"."topic_id" WHERE "posts"."deleted_at" IS NULL AND (topics.archetype <> 'private_message') AND NOT ((topics.category_id IN (NULL))) AND "posts"."post_type" = 1
debugsql (sec): 0.0
debugsql (sql): SELECT COUNT(*) FROM "posts" INNER JOIN "topics" ON "topics"."deleted_at" IS NULL AND "topics"."id" = "posts"."topic_id" WHERE "posts"."deleted_at" IS NULL AND (topics.archetype <> 'private_message') AND NOT ((topics.category_id IN (NULL))) AND "posts"."post_type" = 1 AND (posts.created_at >= '2025-02-01 06:42:19.865947' and posts.created_at < '2025-03-03 06:42:19.865947')
debugsql (sec): 0.0
debugsql (sql): COMMIT
debugsql (sec): 0.0
=> []
discourse(prod)> 

위 내용은 제 콘솔 출력 결과입니다.

여러 플러그인을 설치했지만, 브라우저에서 안전 모드(Private Mode)로 진입해도 백엔드에서 게시물 수가 표시되지 않습니다. 다른 모든 통계는 정상적으로 작동하는 것으로 보이지만, 게시물 수만 아무 결과도 나오지 않아 문제가 어디에 있는지 확신이 서지 않습니다.

2개의 좋아요

감사합니다! 쿼리에는 출처를 알 수 없는 동일한 AND NOT ((topics.category_id IN (NULL))) 절이 포함되어 있습니다. 안전 모드에서도 이 문제가 발생한다면 플러그인을 원인으로 배제할 수 있습니다.

1개의 좋아요

안전 모드로 비활성화되지 않는 서버 측 문제일 수 있다고 생각합니다.

두 분 모두 Private Topics Plugin 이 설치되어 있는 것 같습니다. 이 플러그인과 관련된 문제일 수 있습니다. 1월의 이 커밋 때문일까요? SECURITY: remove private topics category from public_posts · communiteq/discourse-private-topics@08c9668 · GitHub

4개의 좋아요

좋은 지적입니다. 개인 카테고리가 설정되어 있지 않으면 해당 줄을 삽입하지 않아야 한다는 데 저도 동의합니다(오늘 늦게 업데이트할 예정입니다).

하지만 대시보드가 어떻게 깨질 수 있는지는 잘 모르겠습니다.

3개의 좋아요

확실하지는 않지만, 테스트 사이트에 Private Topics 플러그인을 설치하면 이 문제를 재현할 수 있습니다. 카테고리 보안 설정에서 'enable private topics’가 설정된 카테고리가 하나도 없을 때 발생하는 것 같습니다(플러그인이 설치되어 있지만 비활성화된 상태여도 마찬가지입니다). 특정 카테고리에 Private Topics를 활성화하면 대시보드 보고서가 다시 정상적으로 표시됩니다.

수정된 보고서가 추가 조건에서 NULL 값을 처리하지 못하는 것 같습니다.

6개의 좋아요

문제를 재현했고, 수정을 푸시했습니다.

@JammyDodger 님, 감사합니다. 제가 이 문제를 찾느라 얼마나 걸렸을지 모르겠습니다.

(다시 돌아오신 걸 보니 반갑네요)

5개의 좋아요

좋아요, 모두 감사합니다! 해결하기가 정말 어려웠네요…

1개의 좋아요

아 놀랍네요, @JammyDodger 감사합니다. 이게 진짜 미칠 것 같았어요 :zany_face:

4개의 좋아요