diff --git a/ee/app/graphql/mutations/ai/action.rb b/ee/app/graphql/mutations/ai/action.rb
index adcac4e09b32a91fcb9bac6b28dad9b994a0b00e..7913c076e96e671d9ac3b0c4daf0ad07528ea53e 100644
--- a/ee/app/graphql/mutations/ai/action.rb
+++ b/ee/app/graphql/mutations/ai/action.rb
@@ -5,6 +5,8 @@ module Ai
     class Action < BaseMutation
       graphql_name 'AiAction'
 
+      include ::Gitlab::Llm::Concerns::Logger
+
       MUTUALLY_EXCLUSIVE_ARGUMENTS_ERROR = 'Only one method argument is required'
 
       ::Gitlab::Llm::Utils::AiFeaturesCatalogue.external.each_key do |method|
@@ -47,9 +49,36 @@ def ready?(**args)
         super
       end
 
+      # rubocop:disable GraphQL/GraphqlName -- This is unrelated to GraphQL schema.
+      class UnsafeSanitizedPrinter < GraphQL::Language::SanitizedPrinter
+        def redact_argument_value?(...)
+          false
+        end
+      end
+      # rubocop:enable GraphQL/GraphqlName
+
+      def sanitized_query_string
+        return unless Feature.enabled?(:expanded_ai_logging, current_user)
+
+        # rubocop:disable GitlabSecurity/PublicSend -- Workaround for the GraphQL Ruby gem.
+        context.query.send(:with_prepared_ast) do
+          UnsafeSanitizedPrinter.new(context.query, inline_variables: true).sanitized_query_string
+        end
+        # rubocop:enable GitlabSecurity/PublicSend
+      end
+
       def resolve(**attributes)
         verify_rate_limit!
 
+        log_conditional_info(
+          current_user,
+          message: "Received AiAction mutation GraphQL query",
+          event_name: 'ai_action_mutation',
+          ai_component: 'abstraction_layer',
+          user_id: current_user.id,
+          graphql_query: sanitized_query_string
+        )
+
         resource_id, method, options = extract_method_params!(attributes)
 
         check_feature_flag_enabled!(method)
diff --git a/ee/lib/gitlab/llm/concerns/logger.rb b/ee/lib/gitlab/llm/concerns/logger.rb
index c280d526ab3109ddfd460b22e61aa4275c3cb4fe..457d58ecd1a1c0fee3b17e0b7d143034302d52fe 100644
--- a/ee/lib/gitlab/llm/concerns/logger.rb
+++ b/ee/lib/gitlab/llm/concerns/logger.rb
@@ -46,7 +46,8 @@ module Logger
             Attribute.new(:event_type, String),
             Attribute.new(:error_type, String),
             Attribute.new(:fragment, String),
-            Attribute.new(:ai_response_server, String)
+            Attribute.new(:ai_response_server, String),
+            Attribute.new(:graphql_query, String)
           ].freeze
 
         def self.included(base)
diff --git a/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb b/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb
index f6b1f1dd003e10087245d4bf459594900d795475..1e5154f9a1a6dcc11cd40fbc42283d24676cda7c 100644
--- a/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb
+++ b/ee/spec/requests/api/graphql/mutations/projects/chat_spec.rb
@@ -21,6 +21,36 @@
 
   include_context 'with ai features enabled for group'
 
+  it 'logs expanded GraphQL mutation request' do
+    expect_next_instance_of(Mutations::Ai::Action) do |mutation|
+      expect(mutation).to receive(:log_conditional_info).with(
+        instance_of(User),
+        hash_including(graphql_query: instance_of(String))
+      )
+    end
+
+    post_graphql_mutation(mutation, current_user: current_user)
+  end
+
+  context 'when expanded_ai_logging feature flag is disabled' do
+    before do
+      stub_feature_flags(expanded_ai_logging: false)
+    end
+
+    it 'does not log expanded GraphQL mutation request' do
+      expect_next_instance_of(Mutations::Ai::Action) do |mutation|
+        expect(mutation).to receive(:log_conditional_info).with(
+          instance_of(User),
+          hash_including(graphql_query: nil)
+        )
+      end
+
+      expect(Mutations::Ai::Action::UnsafeSanitizedPrinter).not_to receive(:new)
+
+      post_graphql_mutation(mutation, current_user: current_user)
+    end
+  end
+
   context 'when resource is nil' do
     let(:resource) { nil }