DEV Community

Alain Airom
Alain Airom

Posted on • Edited on

Things you can do with IBM Bob if you don’t want to Code!

Using IBM Bob SDLC in documentation mode.

Introduction

In the fast-paced world of software development, it is easy to pigeonhole an AI assistant like IBM Bob SDLC as just another code-crunching engine. While its ability to churn out clean, efficient syntax is undeniable, its true value lies in its versatility across the entire project lifecycle. Whether you are a junior developer looking to bridge the gap between logic and implementation, or a Product Owner, Functional Consultant, or Project Manager navigating the complexities of requirements, Bob adapts to your needs. From drafting comprehensive technical specifications to performing the “detective work” of retro-documentation on legacy systems, IBM Bob is less of a simple tool and more of a multi-faceted collaborator designed to streamline workflows for every stakeholder involved.

To illustrate this, let’s jump into a hypothetical case of retro documentation of a whole application based on a code repository (a GitHub repository). I asked candidly from Bob to provide a detailed an architecture documentation for the IBM Instana Go-Sensor code! And Bob did it for sure 🤓 (even though the code is well documented), but my aim is to showcase one of the document writing capacities of Bob!


TL;DR-What is Instana?

Instana STAN

Instana STAN

At its core, IBM Instana is an enterprise-grade observability and Application Performance Monitoring (APM) platform designed for the complexity of modern, cloud-native environments. Unlike traditional monitoring tools that require manual configuration and struggle with the ephemeral nature of microservices, Instana is built on automation. It utilizes “Agentic AI” and over 250 domain-specific sensors to automatically discover, map, and monitor every component of your technology stack — from mobile front-ends and web browsers down to the underlying infrastructure, including Kubernetes, serverless functions, and even legacy mainframes.


It captures high-fidelity data with one-second granularity and traces every single request without sampling, ensuring that no performance anomaly or error goes unnoticed. By leveraging AI-powered root-cause analysis, Instana doesn’t just alert you that something is wrong; it correlates events to tell you why it happened, drastically reducing the Mean Time to Repair (MTTR). This “democratization of data” allows DevOps, SREs, and Product Owners to move away from reactive “war rooms” and toward proactive optimization, ensuring a seamless and reliable end-user experience across the entire digital journey.


When Bob meets Stan 😂

OK, having introduced Instana, for my test usecase, I gave the following prompt to Bob, and then I show the interactions between Bob and myself!

Read the following Github: https://github.com/instana/go-sensor and provide a full arhitectural document of the repository and waht the code does alongside with mermaid flow charts 
I want the architecture mermaid flow charts added as well
Enter fullscreen mode Exit fullscreen mode

  • Then a whole task list is provided, the user can always stop Bob and give further instructions;

  • Once I validated the tasks (or if you authorize Bob to do specific tasks without approval for all steps…), I got a full architecture document in Markdown format, with revelant flows and a detailed documentation. The one shown below is the high-level architecture schema.

  • There are also several specific area flows provided.

The document contains also description of components and in this case a recap table of “Framework Instrumentation Packages”.

Framework Instrumentation Packages

| Package              | Framework        | Features                    |
| -------------------- | ---------------- | --------------------------- |
| `instagin`           | Gin              | Middleware for HTTP routing |
| `instaecho`          | Echo             | HTTP middleware             |
| `instafiber`         | Fiber            | HTTP middleware             |
| `instamux`           | Gorilla Mux      | HTTP middleware             |
| `instabeego`         | Beego            | HTTP middleware             |
| `instafasthttp`      | FastHTTP         | HTTP middleware             |
| `instagrpc`          | gRPC             | Unary & stream interceptors |
| `instasarama`        | Kafka (Sarama)   | Producer/consumer wrappers  |
| `instaamqp091`       | RabbitMQ         | Publisher/consumer wrappers |
| `instamongo`         | MongoDB          | Command monitoring          |
| `instaredis`         | Redis (go-redis) | Command hooks               |
| `instaredigo`        | Redis (Redigo)   | Connection wrapper          |
| `instagorm`          | GORM             | Callbacks for DB operations |
| `instagocb`          | Couchbase        | Bucket wrapper              |
| `instapgx`           | PostgreSQL (pgx) | Tracer implementation       |
| `instacosmos`        | Azure Cosmos DB  | Client wrapper              |
| `instaawssdk`        | AWS SDK v1       | Service handlers            |
| `instaawsv2`         | AWS SDK v2       | Middleware                  |
| `instalambda`        | AWS Lambda       | Handler wrapper             |
| `instaazurefunction` | Azure Functions  | Handler wrapper             |
| `instagraphql`       | GraphQL          | Resolver middleware         |
Enter fullscreen mode Exit fullscreen mode

Bob can also provide a documentation on specific part or parts of an existing code. Let’s imagine that hypothetically we have an undocumented code or a code in a programming language we do not know!

// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2020

package instana

import (
 "bytes"
 "context"
 "encoding/json"
 "fmt"
 "io"
 "net/http"
 "os"
 "strconv"
 "sync"
 "time"

 "github.com/instana/go-sensor/acceptor"
 "github.com/instana/go-sensor/autoprofile"
)

const awsLambdaAgentFlushPeriod = 2 * time.Second

type lambdaAgent struct {
 Endpoint string
 Key      string
 PID      int

 snapshot serverlessSnapshot

 mu        sync.RWMutex
 spanQueue []Span

 client *http.Client
 logger LeveledLogger
}

func newLambdaAgent(
 serviceName, acceptorEndpoint, agentKey string,
 client *http.Client,
 logger LeveledLogger,
) *lambdaAgent {
 if logger == nil {
  logger = defaultLogger
 }

 if client == nil {
  client = http.DefaultClient
 }

 logger.Debug("initializing aws lambda agent")

 agent := &lambdaAgent{
  Endpoint: acceptorEndpoint,
  Key:      agentKey,
  PID:      os.Getpid(),
  client:   client,
  logger:   logger,
 }

 go func(a *lambdaAgent) {
  t := time.NewTicker(awsLambdaAgentFlushPeriod)
  defer t.Stop()

  for range t.C {
   if err := a.Flush(context.Background()); err != nil {
    a.logger.Error("failed to post collected data: ", err)
   }
  }
 }(agent)

 return agent
}

func (a *lambdaAgent) Ready() bool { return true }

func (a *lambdaAgent) SendMetrics(data acceptor.Metrics) error { return nil }

func (a *lambdaAgent) SendEvent(event *EventData) error { return nil }

func (a *lambdaAgent) SendSpans(spans []Span) error {
 a.enqueueSpans(spans)
 return nil
}

func (a *lambdaAgent) SendProfiles(profiles []autoprofile.Profile) error { return nil }

func (a *lambdaAgent) Flush(ctx context.Context) error {
 snapshot := a.collectSnapshot(a.spanQueue)

 if snapshot.EntityID == "" {
  return ErrAgentNotReady
 }

 from := newServerlessAgentFromS(snapshot.EntityID, "aws")

 payload := struct {
  Metrics metricsPayload `json:"metrics,omitempty"`
  Spans   []Span         `json:"spans,omitempty"`
 }{
  Metrics: metricsPayload{
   Plugins: []acceptor.PluginPayload{
    acceptor.NewAWSLambdaPluginPayload(snapshot.EntityID),
   },
  },
 }

 a.mu.Lock()
 payload.Spans = make([]Span, len(a.spanQueue))
 copy(payload.Spans, a.spanQueue)
 a.spanQueue = a.spanQueue[:0]
 a.mu.Unlock()

 for i := range payload.Spans {
  payload.Spans[i].From = from
 }

 buf := bytes.NewBuffer(nil)
 if err := json.NewEncoder(buf).Encode(payload); err != nil {
  return fmt.Errorf("failed to marshal traces payload: %s", err)
 }

 req, err := http.NewRequest(http.MethodPost, a.Endpoint+"/bundle", buf)
 if err != nil {
  a.enqueueSpans(payload.Spans)
  return fmt.Errorf("failed to prepare send traces request: %s", err)
 }

 req.Header.Set("Content-Type", "application/json")

 if err := a.sendRequest(req.WithContext(ctx)); err != nil {
  a.enqueueSpans(payload.Spans)
  return fmt.Errorf("failed to send traces, will retry later: %s", err)
 }

 return nil
}

func (a *lambdaAgent) enqueueSpans(spans []Span) {
 a.mu.Lock()
 defer a.mu.Unlock()

 a.spanQueue = append(a.spanQueue, spans...)
}

func (a *lambdaAgent) sendRequest(req *http.Request) error {
 a.mu.RLock()
 host := a.snapshot.Host
 a.mu.RUnlock()

 req.Header.Set("X-Instana-Host", host)
 req.Header.Set("X-Instana-Key", a.Key)
 req.Header.Set("X-Instana-Time", strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10))

 resp, err := a.client.Do(req)
 if err != nil {
  return fmt.Errorf("failed to send request to the serverless agent: %s", err)
 }

 defer resp.Body.Close()

 if resp.StatusCode >= http.StatusBadRequest {
  respBody, err := io.ReadAll(resp.Body)
  if err != nil {
   a.logger.Debug("failed to read serverless agent response: ", err)
   return nil
  }

  a.logger.Info("serverless agent has responded with ", resp.Status, ": ", string(respBody))
  return nil
 }

 io.CopyN(io.Discard, resp.Body, 1<<20)

 return nil
}

func (a *lambdaAgent) collectSnapshot(spans []Span) serverlessSnapshot {
 a.mu.RLock()
 entityID := a.snapshot.EntityID
 a.mu.RUnlock()

 if entityID != "" {
  return a.snapshot
 }

 // searching for the lambda entry span in reverse order, since it's
 // more likely to be finished last
 for i := len(spans) - 1; i >= 0; i-- {
  sp, ok := spans[i].Data.(AWSLambdaSpanData)
  if !ok {
   continue
  }

  a.mu.Lock()
  a.snapshot = serverlessSnapshot{
   EntityID: sp.Snapshot.ARN,
   Host:     sp.Snapshot.ARN,
  }
  a.mu.Unlock()
  a.logger.Debug("collected snapshot")

  break
 }

 return a.snapshot
}
Enter fullscreen mode Exit fullscreen mode
  • I gave the following prompt to Bob ⤵️
Provide a document explainig the "lambda_agent.go" functionality, what it does and how it can be used
Enter fullscreen mode Exit fullscreen mode
  • Not only Bob provides the very detailed documentation, but also a full detailed component architecture of tho code! I provide hereafter a portion of the document generated.
-Core Components

The Lambda agent consists of several key components:

1. **Span Queue**: Thread-safe buffer for collecting trace spans
2. **Snapshot Collector**: Captures Lambda function metadata (ARN, version, etc.)
3. **Periodic Flusher**: Automatically sends data every 2 seconds
4. **HTTP Client**: Handles communication with Instana backend

-Key Features

-1. Automatic Span Collection

The agent automatically collects and queues trace spans generated during Lambda execution:

- **Thread-safe queuing**: Uses mutex locks to prevent race conditions
- **Automatic batching**: Groups spans for efficient transmission
- **Retry mechanism**: Re-queues spans if sending fails

-2. Serverless Snapshot

Captures essential Lambda function metadata:

- **ARN (Amazon Resource Name)**: Unique identifier for the Lambda function
- **Host information**: Lambda execution environment details
- **Process ID**: Current Lambda container process

-3. Periodic Flushing

Automatically sends collected data at regular intervals:

- **Flush period**: 2 seconds (configurable via `awsLambdaAgentFlushPeriod`)
- **Background goroutine**: Non-blocking operation
- **Context-aware**: Respects cancellation and timeouts

-4. Metrics Integration

Includes AWS Lambda plugin payload with each flush:

- **Entity identification**: Links spans to Lambda function
- **Cloud provider metadata**: AWS-specific information
- **Performance metrics**: Execution time, cold starts, etc.
Enter fullscreen mode Exit fullscreen mode


-Snapshot Collection

The agent extracts Lambda metadata from the first `aws.lambda.entry` span:

1. Searches span queue in reverse order (most recent first)
2. Finds span with `AWSLambdaSpanData` type
3. Extracts ARN from span snapshot
4. Caches snapshot for subsequent flushes

-Configuration

-Environment Variables

The Lambda agent is automatically configured when running in AWS Lambda environment:

| Variable               | Description                        | Required | Default |
| ---------------------- | ---------------------------------- | -------- | ------- |
| `INSTANA_AGENT_KEY`    | Instana backend authentication key | Yes      | -       |
| `INSTANA_ENDPOINT_URL` | Instana backend endpoint           | Yes      | -       |
| `AWS_EXECUTION_ENV`    | AWS Lambda execution environment   | Auto-set | -       |
| `INSTANA_ZONE`         | Availability zone tag              | No       | -       |
| `INSTANA_TAGS`         | Custom tags (comma-separated)      | No       | -       |
| `INSTANA_SECRETS`      | Secret patterns to redact          | No       | -       |

Enter fullscreen mode Exit fullscreen mode

Conclusion

Ultimately, the integration of IBM Bob SDLC into the analysis of a public repository demonstrates that its value extends far beyond the IDE. By processing the raw complexity of an existing codebase, Bob acts as a bridge between technical debt and clarity. In this specific scenario, its ability to generate retro-documentation — essentially reverse-engineering the “why” behind the “what” — allows teams to reclaim lost knowledge without manual archeology. When paired with application architecture mapping and granular code documentation, Bob transforms a dense thicket of files into a transparent, navigable roadmap.

This synergy proves that Bob is an essential asset for more than just the engineering team. For the Product Owner or Project Manager, these documentation capabilities provide a high-level view of system dependencies and health; for the Functional Consultant, they offer a clear understanding of logic flows. By automating the most tedious aspects of the SDLC, Bob ensures that whether you are onboarding a new junior developer or planning a massive architectural migration, the “source of truth” is always documented, up-to-date, and accessible to everyone involved.

>>> Thanks for reading <<<

Links

Top comments (0)